From 24b53c6e714f30e50d7ccc5d3c1d30cd35907d8b Mon Sep 17 00:00:00 2001 From: Chris Moeller Date: Sun, 13 Oct 2013 13:02:19 -0700 Subject: [PATCH] Implemented 2SF format support --- .../vio2sf/vio2sf.xcodeproj/project.pbxproj | 459 + .../vio2sf/vio2sf/en.lproj/InfoPlist.strings | 2 + .../vio2sf/vio2sf/src/vio2sf/desmume/ARM9.h | 31 + .../vio2sf/vio2sf/src/vio2sf/desmume/COPYING | 340 + .../vio2sf/vio2sf/src/vio2sf/desmume/FIFO.c | 65 + .../vio2sf/vio2sf/src/vio2sf/desmume/FIFO.h | 51 + .../vio2sf/vio2sf/src/vio2sf/desmume/GPU.c | 95 + .../vio2sf/vio2sf/src/vio2sf/desmume/GPU.h | 808 ++ .../vio2sf/vio2sf/src/vio2sf/desmume/MMU.c | 3468 ++++++++ .../vio2sf/vio2sf/src/vio2sf/desmume/MMU.h | 194 + .../vio2sf/src/vio2sf/desmume/NDSSystem.c | 750 ++ .../vio2sf/src/vio2sf/desmume/NDSSystem.h | 250 + .../vio2sf/vio2sf/src/vio2sf/desmume/SPU.cpp | 1074 +++ .../vio2sf/vio2sf/src/vio2sf/desmume/SPU.h | 186 + .../src/vio2sf/desmume/arm_instructions.c | 7926 +++++++++++++++++ .../src/vio2sf/desmume/arm_instructions.h | 31 + .../vio2sf/vio2sf/src/vio2sf/desmume/armcpu.c | 582 ++ .../vio2sf/vio2sf/src/vio2sf/desmume/armcpu.h | 290 + .../vio2sf/vio2sf/src/vio2sf/desmume/bios.c | 1080 +++ .../vio2sf/vio2sf/src/vio2sf/desmume/bios.h | 32 + .../vio2sf/vio2sf/src/vio2sf/desmume/bits.h | 44 + .../vio2sf/vio2sf/src/vio2sf/desmume/config.h | 28 + .../vio2sf/vio2sf/src/vio2sf/desmume/cp15.c | 592 ++ .../vio2sf/vio2sf/src/vio2sf/desmume/cp15.h | 94 + .../vio2sf/vio2sf/src/vio2sf/desmume/debug.h | 11 + .../vio2sf/vio2sf/src/vio2sf/desmume/dscard.h | 34 + .../src/vio2sf/desmume/instruction_tabdef.inc | 4400 +++++++++ .../vio2sf/vio2sf/src/vio2sf/desmume/matrix.c | 257 + .../vio2sf/vio2sf/src/vio2sf/desmume/matrix.h | 51 + .../vio2sf/vio2sf/src/vio2sf/desmume/mc.c | 121 + .../vio2sf/vio2sf/src/vio2sf/desmume/mc.h | 94 + .../vio2sf/vio2sf/src/vio2sf/desmume/mem.h | 141 + .../vio2sf/src/vio2sf/desmume/registers.h | 333 + .../vio2sf/src/vio2sf/desmume/spu_exports.h | 36 + .../vio2sf/vio2sf/src/vio2sf/desmume/state.c | 766 ++ .../vio2sf/vio2sf/src/vio2sf/desmume/state.h | 96 + .../src/vio2sf/desmume/thumb_instructions.c | 944 ++ .../src/vio2sf/desmume/thumb_instructions.h | 30 + .../src/vio2sf/desmume/thumb_tabdef.inc | 1111 +++ .../vio2sf/vio2sf/src/vio2sf/desmume/types.h | 151 + Frameworks/vio2sf/vio2sf/vio2sf-Info.plist | 30 + Info.plist | 15 + .../HighlyComplete.xcodeproj/project.pbxproj | 49 + .../HighlyComplete/HCDecoder.mm | 320 +- 44 files changed, 27444 insertions(+), 18 deletions(-) create mode 100644 Frameworks/vio2sf/vio2sf.xcodeproj/project.pbxproj create mode 100644 Frameworks/vio2sf/vio2sf/en.lproj/InfoPlist.strings create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/ARM9.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/COPYING create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/FIFO.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/FIFO.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/GPU.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/GPU.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/MMU.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/MMU.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/NDSSystem.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/NDSSystem.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/SPU.cpp create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/SPU.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/arm_instructions.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/arm_instructions.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/armcpu.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/armcpu.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bios.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bios.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bits.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/config.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/cp15.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/cp15.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/debug.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/dscard.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/instruction_tabdef.inc create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/matrix.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/matrix.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mc.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mc.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mem.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/registers.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/spu_exports.h create mode 100644 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/state.c create mode 100644 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/state.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_instructions.c create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_instructions.h create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_tabdef.inc create mode 100755 Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/types.h create mode 100644 Frameworks/vio2sf/vio2sf/vio2sf-Info.plist diff --git a/Frameworks/vio2sf/vio2sf.xcodeproj/project.pbxproj b/Frameworks/vio2sf/vio2sf.xcodeproj/project.pbxproj new file mode 100644 index 000000000..64e5aeb40 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf.xcodeproj/project.pbxproj @@ -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 = ""; }; + 83DE0C13180A9BD400269051 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 83DE0C46180A9CA400269051 /* ARM9.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARM9.h; sourceTree = ""; }; + 83DE0C47180A9CA400269051 /* arm_instructions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arm_instructions.c; sourceTree = ""; }; + 83DE0C48180A9CA400269051 /* arm_instructions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arm_instructions.h; sourceTree = ""; }; + 83DE0C49180A9CA400269051 /* armcpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = armcpu.c; sourceTree = ""; }; + 83DE0C4A180A9CA400269051 /* armcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = armcpu.h; sourceTree = ""; }; + 83DE0C4B180A9CA400269051 /* bios.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bios.c; sourceTree = ""; }; + 83DE0C4C180A9CA400269051 /* bios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bios.h; sourceTree = ""; }; + 83DE0C4D180A9CA400269051 /* bits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bits.h; sourceTree = ""; }; + 83DE0C4E180A9CA400269051 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; + 83DE0C4F180A9CA400269051 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COPYING; sourceTree = ""; }; + 83DE0C50180A9CA400269051 /* cp15.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cp15.c; sourceTree = ""; }; + 83DE0C51180A9CA400269051 /* cp15.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cp15.h; sourceTree = ""; }; + 83DE0C52180A9CA400269051 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; + 83DE0C53180A9CA400269051 /* dscard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dscard.h; sourceTree = ""; }; + 83DE0C54180A9CA400269051 /* FIFO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = FIFO.c; sourceTree = ""; }; + 83DE0C55180A9CA400269051 /* FIFO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIFO.h; sourceTree = ""; }; + 83DE0C56180A9CA400269051 /* GPU.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = GPU.c; sourceTree = ""; }; + 83DE0C57180A9CA400269051 /* GPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPU.h; sourceTree = ""; }; + 83DE0C58180A9CA400269051 /* instruction_tabdef.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = instruction_tabdef.inc; sourceTree = ""; }; + 83DE0C59180A9CA400269051 /* matrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = matrix.c; sourceTree = ""; }; + 83DE0C5A180A9CA400269051 /* matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix.h; sourceTree = ""; }; + 83DE0C5B180A9CA400269051 /* mc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc.c; sourceTree = ""; }; + 83DE0C5C180A9CA400269051 /* mc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mc.h; sourceTree = ""; }; + 83DE0C5D180A9CA400269051 /* mem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mem.h; sourceTree = ""; }; + 83DE0C5E180A9CA400269051 /* MMU.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MMU.c; sourceTree = ""; }; + 83DE0C5F180A9CA400269051 /* MMU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMU.h; sourceTree = ""; }; + 83DE0C60180A9CA400269051 /* NDSSystem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = NDSSystem.c; sourceTree = ""; }; + 83DE0C61180A9CA400269051 /* NDSSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NDSSystem.h; sourceTree = ""; }; + 83DE0C62180A9CA400269051 /* registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = registers.h; sourceTree = ""; }; + 83DE0C66180A9CA400269051 /* SPU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SPU.cpp; sourceTree = ""; }; + 83DE0C67180A9CA400269051 /* SPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPU.h; sourceTree = ""; }; + 83DE0C68180A9CA400269051 /* spu_exports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spu_exports.h; sourceTree = ""; }; + 83DE0C69180A9CA400269051 /* thumb_instructions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = thumb_instructions.c; sourceTree = ""; }; + 83DE0C6A180A9CA400269051 /* thumb_instructions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thumb_instructions.h; sourceTree = ""; }; + 83DE0C6B180A9CA400269051 /* thumb_tabdef.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = thumb_tabdef.inc; sourceTree = ""; }; + 83DE0C6C180A9CA400269051 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; + 83DE0CB7180A9FD000269051 /* state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = state.c; sourceTree = ""; }; + 83DE0CB9180A9FE300269051 /* state.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = state.h; sourceTree = ""; }; +/* 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 = ""; + }; + 83DE0C07180A9BD400269051 /* Products */ = { + isa = PBXGroup; + children = ( + 83DE0C06180A9BD400269051 /* vio2sf.framework */, + ); + name = Products; + sourceTree = ""; + }; + 83DE0C08180A9BD400269051 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 83DE0C0B180A9BD400269051 /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 83DE0C0B180A9BD400269051 /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 83DE0C0F180A9BD400269051 /* vio2sf */ = { + isa = PBXGroup; + children = ( + 83DE0C44180A9CA400269051 /* vio2sf */, + 83DE0C10180A9BD400269051 /* Supporting Files */, + ); + path = vio2sf; + sourceTree = ""; + }; + 83DE0C10180A9BD400269051 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 83DE0C11180A9BD400269051 /* vio2sf-Info.plist */, + 83DE0C12180A9BD400269051 /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 83DE0C44180A9CA400269051 /* vio2sf */ = { + isa = PBXGroup; + children = ( + 83DE0C45180A9CA400269051 /* desmume */, + ); + name = vio2sf; + path = src/vio2sf; + sourceTree = ""; + }; + 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 = ""; + }; +/* 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 = ""; + }; +/* 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 */; +} diff --git a/Frameworks/vio2sf/vio2sf/en.lproj/InfoPlist.strings b/Frameworks/vio2sf/vio2sf/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/ARM9.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/ARM9.h new file mode 100755 index 000000000..4b7883ee8 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/ARM9.h @@ -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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/COPYING b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/COPYING new file mode 100755 index 000000000..d60c31a97 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/COPYING @@ -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. + + + Copyright (C) + + 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. + + , 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. diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/FIFO.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/FIFO.c new file mode 100755 index 000000000..c86017f71 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/FIFO.c @@ -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; +} diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/FIFO.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/FIFO.h new file mode 100755 index 000000000..86e282902 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/FIFO.h @@ -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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/GPU.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/GPU.c new file mode 100755 index 000000000..b0a5c78d9 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/GPU.c @@ -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 +#include +#include +#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); + +} diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/GPU.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/GPU.h new file mode 100755 index 000000000..6967d7c94 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/GPU.h @@ -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 +#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 + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/MMU.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/MMU.c new file mode 100755 index 000000000..05cc74d7d --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/MMU.c @@ -0,0 +1,3468 @@ +/* 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 +*/ + +//#define RENDER3D + +#include +#include +#include + +//#include "gl_vertex.h" +#include "spu_exports.h" + +#include "state.h" + +#include "MMU.h" + +#include "debug.h" +#include "NDSSystem.h" +//#include "cflash.h" +#define cflash_read(s,a) 0 +#define cflash_write(s,a,d) +#include "cp15.h" +//#include "wifi.h" +#include "registers.h" + +#if VIO2SF_GPU_ENABLE +#include "render3D.h" +#else +#define GPU_setVideoProp(p1, p2) +#define GPU_setBGProp(p1, p2, p3) + +#define GPU_setBLDCNT(p1, p2) +#define GPU_setBLDALPHA(p1, p2) +#define GPU_setBLDY(p1, p2) +#define GPU_setMOSAIC(p1, p2) + + +#define GPU_remove(p1,p2) +#define GPU_addBack(p1,p2) + +#define GPU_ChangeGraphicsCore(p1) 0 + +#define GPU_set_DISPCAPCNT(p1, p2) +#define GPU_ligne(p1, p2) +#define GPU_setMasterBrightness(p1, p2) + +#define GPU_setWIN0_H(p1, p2) +#define GPU_setWIN0_H0(p1, p2) +#define GPU_setWIN0_H1(p1, p2) + +#define GPU_setWIN0_V(p1, p2) +#define GPU_setWIN0_V0(p1, p2) +#define GPU_setWIN0_V1(p1, p2) + +#define GPU_setWIN1_H(p1, p2) +#define GPU_setWIN1_H0(p1, p2) +#define GPU_setWIN1_H1(p1, p2) + +#define GPU_setWIN1_V(p1, p2) +#define GPU_setWIN1_V0(p1, p2) +#define GPU_setWIN1_V1(p1, p2) + +#define GPU_setWININ(p1, p2) +#define GPU_setWININ0(p1, p2) +#define GPU_setWININ1(p1, p2) + +#define GPU_setWINOUT16(p1, p2) +#define GPU_setWINOUT(p1, p2) +#define GPU_setWINOBJ(p1, p2) + +#define GPU_setBLDCNT_LOW(p1, p2) +#define GPU_setBLDCNT_HIGH(p1, p2) +#define GPU_setBLDCNT(p1, p2) + +#define GPU_setBLDALPHA(p1, p2) +#define GPU_setBLDALPHA_EVA(p1, p2) +#define GPU_setBLDALPHA_EVB(p1, p2) + +#define GPU_setBLDY_EVY(p1, p2) +#endif + +#define ROM_MASK 3 + +/* + * + */ +//#define PROFILE_MEMORY_ACCESS 1 +#define EARLY_MEMORY_ACCESS 1 + +#define INTERNAL_DTCM_READ 1 +#define INTERNAL_DTCM_WRITE 1 + +//#define LOG_CARD +//#define LOG_GPU +//#define LOG_DMA +//#define LOG_DMA2 +//#define LOG_DIV + +#define DUP2(x) x, x +#define DUP4(x) x, x, x, x +#define DUP8(x) x, x, x, x, x, x, x, x +#define DUP16(x) x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x + +#if 0 +#endif + + +const u32 MMU_ARM9_WAIT16[16]={ + 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1, +}; + +const u32 MMU_ARM9_WAIT32[16]={ + 1, 1, 1, 1, 1, 2, 2, 1, 8, 8, 5, 1, 1, 1, 1, 1, +}; + +const u32 MMU_ARM7_WAIT16[16]={ + 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1, +}; + +const u32 MMU_ARM7_WAIT32[16]={ + 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 5, 1, 1, 1, 1, 1, +}; + +void MMU_Init(NDS_state *state) { + int i; + + LOG("MMU init\n"); + + memset(state->MMU, 0, sizeof(MMU_struct)); + + state->MMU->CART_ROM = state->MMU->UNUSED_RAM; + + for(i = 0x80; i<0xA0; ++i) + { + state->MMU_ARM9_MEM_MAP[i] = state->MMU->CART_ROM; + state->MMU_ARM7_MEM_MAP[i] = state->MMU->CART_ROM; + } + + state->MMU->MMU_MEM[0] = state->MMU_ARM9_MEM_MAP; + state->MMU->MMU_MEM[1] = state->MMU_ARM7_MEM_MAP; + state->MMU->MMU_MASK[0]= state->MMU_ARM9_MEM_MASK; + state->MMU->MMU_MASK[1] = state->MMU_ARM7_MEM_MASK; + + state->MMU->ITCMRegion = 0x00800000; + + state->MMU->MMU_WAIT16[0] = MMU_ARM9_WAIT16; + state->MMU->MMU_WAIT16[1] = MMU_ARM7_WAIT16; + state->MMU->MMU_WAIT32[0] = MMU_ARM9_WAIT32; + state->MMU->MMU_WAIT32[1] = MMU_ARM7_WAIT32; + + for(i = 0;i < 16;i++) + FIFOInit(state->MMU->fifos + i); + + mc_init(&state->MMU->fw, MC_TYPE_FLASH); /* init fw device */ + mc_alloc(&state->MMU->fw, NDS_FW_SIZE_V1); + state->MMU->fw.fp = NULL; + + // Init Backup Memory device, this should really be done when the rom is loaded + mc_init(&state->MMU->bupmem, MC_TYPE_AUTODETECT); + mc_alloc(&state->MMU->bupmem, 1); + state->MMU->bupmem.fp = NULL; + +} + +void MMU_DeInit(NDS_state *state) { + LOG("MMU deinit\n"); +// if (MMU->fw.fp) +// fclose(MMU->fw.fp); + mc_free(&state->MMU->fw); +// if (MMU->bupmem.fp) +// fclose(MMU->bupmem.fp); + mc_free(&state->MMU->bupmem); +} + +//Card rom & ram + + +void MMU_clearMem(NDS_state *state) +{ + int i; + + memset(state->ARM9Mem->ARM9_ABG, 0, 0x080000); + memset(state->ARM9Mem->ARM9_AOBJ, 0, 0x040000); + memset(state->ARM9Mem->ARM9_BBG, 0, 0x020000); + memset(state->ARM9Mem->ARM9_BOBJ, 0, 0x020000); + memset(state->ARM9Mem->ARM9_DTCM, 0, 0x4000); + memset(state->ARM9Mem->ARM9_ITCM, 0, 0x8000); + memset(state->ARM9Mem->ARM9_LCD, 0, 0x0A4000); + memset(state->ARM9Mem->ARM9_OAM, 0, 0x0800); + memset(state->ARM9Mem->ARM9_REG, 0, 0x01000000); + memset(state->ARM9Mem->ARM9_VMEM, 0, 0x0800); + memset(state->ARM9Mem->ARM9_WRAM, 0, 0x01000000); + memset(state->ARM9Mem->MAIN_MEM, 0, 0x400000); + + memset(state->ARM9Mem->blank_memory, 0, 0x020000); + + memset(state->MMU->ARM7_ERAM, 0, 0x010000); + memset(state->MMU->ARM7_REG, 0, 0x010000); + + for(i = 0;i < 16;i++) + FIFOInit(state->MMU->fifos + i); + + state->MMU->DTCMRegion = 0; + state->MMU->ITCMRegion = 0x00800000; + + memset(state->MMU->timer, 0, sizeof(u16) * 2 * 4); + memset(state->MMU->timerMODE, 0, sizeof(s32) * 2 * 4); + memset(state->MMU->timerON, 0, sizeof(u32) * 2 * 4); + memset(state->MMU->timerRUN, 0, sizeof(u32) * 2 * 4); + memset(state->MMU->timerReload, 0, sizeof(u16) * 2 * 4); + + memset(state->MMU->reg_IME, 0, sizeof(u32) * 2); + memset(state->MMU->reg_IE, 0, sizeof(u32) * 2); + memset(state->MMU->reg_IF, 0, sizeof(u32) * 2); + + memset(state->MMU->DMAStartTime, 0, sizeof(u32) * 2 * 4); + memset(state->MMU->DMACycle, 0, sizeof(s32) * 2 * 4); + memset(state->MMU->DMACrt, 0, sizeof(u32) * 2 * 4); + memset(state->MMU->DMAing, 0, sizeof(BOOL) * 2 * 4); + + memset(state->MMU->dscard, 0, sizeof(nds_dscard) * 2); + + state->MainScreen->offset = 192; + state->SubScreen->offset = 0; + + /* setup the texture slot pointers */ +#if 0 + state->ARM9Mem->textureSlotAddr[0] = state->ARM9Mem->blank_memory; + state->ARM9Mem->textureSlotAddr[1] = state->ARM9Mem->blank_memory; + state->ARM9Mem->textureSlotAddr[2] = state->ARM9Mem->blank_memory; + state->ARM9Mem->textureSlotAddr[3] = state->ARM9Mem->blank_memory; +#else + state->ARM9Mem->textureSlotAddr[0] = &state->ARM9Mem->ARM9_LCD[0x20000 * 0]; + state->ARM9Mem->textureSlotAddr[1] = &state->ARM9Mem->ARM9_LCD[0x20000 * 1]; + state->ARM9Mem->textureSlotAddr[2] = &state->ARM9Mem->ARM9_LCD[0x20000 * 2]; + state->ARM9Mem->textureSlotAddr[3] = &state->ARM9Mem->ARM9_LCD[0x20000 * 3]; +#endif +} + +/* the VRAM blocks keep their content even when not blended in */ +/* to ensure that we write the content back to the LCD ram */ +/* FIXME: VRAM Bank E,F,G,H,I missing */ +void MMU_VRAMWriteBackToLCD(NDS_state *state, u8 block) +{ + u8 *destination; + u8 *source; + u32 size ; + u8 VRAMBankCnt; + #if 1 + return ; + #endif + destination = 0 ; + source = 0; + VRAMBankCnt = MMU_read8(state, ARMCPU_ARM9,REG_VRAMCNTA+block) ; + switch (block) + { + case 0: // Bank A + destination = state->ARM9Mem->ARM9_LCD ; + size = 0x20000 ; + break ; + case 1: // Bank B + destination = state->ARM9Mem->ARM9_LCD + 0x20000 ; + size = 0x20000 ; + break ; + case 2: // Bank C + destination = state->ARM9Mem->ARM9_LCD + 0x40000 ; + size = 0x20000 ; + break ; + case 3: // Bank D + destination = state->ARM9Mem->ARM9_LCD + 0x60000 ; + size = 0x20000 ; + break ; + case 4: // Bank E + destination = state->ARM9Mem->ARM9_LCD + 0x80000 ; + size = 0x10000 ; + break ; + case 5: // Bank F + destination = state->ARM9Mem->ARM9_LCD + 0x90000 ; + size = 0x4000 ; + break ; + case 6: // Bank G + destination = state->ARM9Mem->ARM9_LCD + 0x94000 ; + size = 0x4000 ; + break ; + case 8: // Bank H + destination = state->ARM9Mem->ARM9_LCD + 0x98000 ; + size = 0x8000 ; + break ; + case 9: // Bank I + destination = state->ARM9Mem->ARM9_LCD + 0xA0000 ; + size = 0x4000 ; + break ; + default: + return ; + } + switch (VRAMBankCnt & 7) { + case 0: + /* vram is allready stored at LCD, we dont need to write it back */ + state->MMU->vScreen = 1; + break ; + case 1: + switch(block){ + case 0: + case 1: + case 2: + case 3: + /* banks are in use for BG at ABG + ofs * 0x20000 */ + source = state->ARM9Mem->ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ; + break ; + case 4: + /* bank E is in use at ABG */ + source = state->ARM9Mem->ARM9_ABG ; + break; + case 5: + case 6: + /* banks are in use for BG at ABG + (0x4000*OFS.0)+(0x10000*OFS.1)*/ + source = state->ARM9Mem->ARM9_ABG + (((VRAMBankCnt >> 3) & 1) * 0x4000) + (((VRAMBankCnt >> 2) & 1) * 0x10000) ; + break; + case 8: + /* bank H is in use at BBG */ + source = state->ARM9Mem->ARM9_BBG ; + break ; + case 9: + /* bank I is in use at BBG */ + source = state->ARM9Mem->ARM9_BBG + 0x8000 ; + break; + default: return ; + } + break ; + case 2: + if (block < 2) + { + /* banks A,B are in use for OBJ at AOBJ + ofs * 0x20000 */ + source = state->ARM9Mem->ARM9_AOBJ + ((VRAMBankCnt >> 3) & 1) * 0x20000 ; + } else return ; + break ; + case 4: + switch(block){ + case 2: + /* bank C is in use at BBG */ + source = state->ARM9Mem->ARM9_BBG ; + break ; + case 3: + /* bank D is in use at BOBJ */ + source = state->ARM9Mem->ARM9_BOBJ ; + break ; + default: return ; + } + break ; + default: + return ; + } + if (!destination) return ; + if (!source) return ; + memcpy(destination,source,size) ; +} + +void MMU_VRAMReloadFromLCD(NDS_state *state, u8 block,u8 VRAMBankCnt) +{ + u8 *destination; + u8 *source; + u32 size; + #if 1 + return ; + #endif + destination = 0; + source = 0; + size = 0; + switch (block) + { + case 0: // Bank A + source = state->ARM9Mem->ARM9_LCD ; + size = 0x20000 ; + break ; + case 1: // Bank B + source = state->ARM9Mem->ARM9_LCD + 0x20000 ; + size = 0x20000 ; + break ; + case 2: // Bank C + source = state->ARM9Mem->ARM9_LCD + 0x40000 ; + size = 0x20000 ; + break ; + case 3: // Bank D + source = state->ARM9Mem->ARM9_LCD + 0x60000 ; + size = 0x20000 ; + break ; + case 4: // Bank E + source = state->ARM9Mem->ARM9_LCD + 0x80000 ; + size = 0x10000 ; + break ; + case 5: // Bank F + source = state->ARM9Mem->ARM9_LCD + 0x90000 ; + size = 0x4000 ; + break ; + case 6: // Bank G + source = state->ARM9Mem->ARM9_LCD + 0x94000 ; + size = 0x4000 ; + break ; + case 8: // Bank H + source = state->ARM9Mem->ARM9_LCD + 0x98000 ; + size = 0x8000 ; + break ; + case 9: // Bank I + source = state->ARM9Mem->ARM9_LCD + 0xA0000 ; + size = 0x4000 ; + break ; + default: + return ; + } + switch (VRAMBankCnt & 7) { + case 0: + /* vram is allready stored at LCD, we dont need to write it back */ + state->MMU->vScreen = 1; + break ; + case 1: + if (block < 4) + { + /* banks are in use for BG at ABG + ofs * 0x20000 */ + destination = state->ARM9Mem->ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ; + } else return ; + break ; + case 2: + switch(block){ + case 0: + case 1: + case 2: + case 3: + /* banks are in use for BG at ABG + ofs * 0x20000 */ + destination = state->ARM9Mem->ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ; + break ; + case 4: + /* bank E is in use at ABG */ + destination = state->ARM9Mem->ARM9_ABG ; + break; + case 5: + case 6: + /* banks are in use for BG at ABG + (0x4000*OFS.0)+(0x10000*OFS.1)*/ + destination = state->ARM9Mem->ARM9_ABG + (((VRAMBankCnt >> 3) & 1) * 0x4000) + (((VRAMBankCnt >> 2) & 1) * 0x10000) ; + break; + case 8: + /* bank H is in use at BBG */ + destination = state->ARM9Mem->ARM9_BBG ; + break ; + case 9: + /* bank I is in use at BBG */ + destination = state->ARM9Mem->ARM9_BBG + 0x8000 ; + break; + default: return ; + } + break ; + case 4: + switch(block){ + case 2: + /* bank C is in use at BBG */ + destination = state->ARM9Mem->ARM9_BBG ; + break ; + case 3: + /* bank D is in use at BOBJ */ + destination = state->ARM9Mem->ARM9_BOBJ ; + break ; + default: return ; + } + break ; + default: + return ; + } + if (!destination) return ; + if (!source) return ; + memcpy(destination,source,size) ; +} + +void MMU_setRom(NDS_state *state, u8 * rom, u32 mask) +{ + unsigned int i; + state->MMU->CART_ROM = rom; + + for(i = 0x80; i<0xA0; ++i) + { + state->MMU_ARM9_MEM_MAP[i] = rom; + state->MMU_ARM7_MEM_MAP[i] = rom; + state->MMU_ARM9_MEM_MASK[i] = mask; + state->MMU_ARM7_MEM_MASK[i] = mask; + } + state->rom_mask = mask; +} + +void MMU_unsetRom(NDS_state *state) +{ + unsigned int i; + state->MMU->CART_ROM=state->MMU->UNUSED_RAM; + + for(i = 0x80; i<0xA0; ++i) + { + state->MMU_ARM9_MEM_MAP[i] = state->MMU->UNUSED_RAM; + state->MMU_ARM7_MEM_MAP[i] = state->MMU->UNUSED_RAM; + state->MMU_ARM9_MEM_MASK[i] = ROM_MASK; + state->MMU_ARM7_MEM_MASK[i] = ROM_MASK; + } + state->rom_mask = ROM_MASK; +} + +u8 FASTCALL MMU_read8(NDS_state *state, u32 proc, u32 adr) +{ +#ifdef INTERNAL_DTCM_READ + if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==state->MMU->DTCMRegion)) + { + return state->ARM9Mem->ARM9_DTCM[adr&0x3FFF]; + } +#endif + + // CFlash reading, Mic + if ((adr>=0x9000000)&&(adr<0x9900000)) + return (unsigned char)cflash_read(state, adr); + +#ifdef EXPERIMENTAL_WIFI + /* wifi mac access */ + if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000)) + { + if (adr & 1) + return (WIFI_read16(&state->wifiMac,adr) >> 8) & 0xFF; + else + return WIFI_read16(&state->wifiMac,adr) & 0xFF; + } +#endif + + return state->MMU->MMU_MEM[proc][(adr>>20)&0xFF][adr&state->MMU->MMU_MASK[proc][(adr>>20)&0xFF]]; +} + + + +u16 FASTCALL MMU_read16(NDS_state *state, u32 proc, u32 adr) +{ +#ifdef INTERNAL_DTCM_READ + if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == state->MMU->DTCMRegion)) + { + /* Returns data from DTCM (ARM9 only) */ + return T1ReadWord(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF); + } +#endif + + // CFlash reading, Mic + if ((adr>=0x08800000)&&(adr<0x09900000)) + return (unsigned short)cflash_read(state, adr); + +#ifdef EXPERIMENTAL_WIFI + /* wifi mac access */ + if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000)) + return WIFI_read16(&state->wifiMac,adr) ; +#endif + + adr &= 0x0FFFFFFF; + + if(adr&0x04000000) + { + /* Adress is an IO register */ + switch(adr) + { + +#if VIO2SF_GPU_ENABLE + case 0x04000604: + return (state->gpu3D->NDS_3D_GetNumPolys(state->gpu3D)&2047); + case 0x04000606: + return (state->gpu3D->NDS_3D_GetNumVertex(state->gpu3D)&8191); +#endif + + case REG_IPCFIFORECV : /* TODO (clear): ??? */ + state->execute = FALSE; + return 1; + + case REG_IME : + return (u16)state->MMU->reg_IME[proc]; + + case REG_IE : + return (u16)state->MMU->reg_IE[proc]; + case REG_IE + 2 : + return (u16)(state->MMU->reg_IE[proc]>>16); + + case REG_IF : + return (u16)state->MMU->reg_IF[proc]; + case REG_IF + 2 : + return (u16)(state->MMU->reg_IF[proc]>>16); + + case REG_TM0CNTL : + case REG_TM1CNTL : + case REG_TM2CNTL : + case REG_TM3CNTL : + return state->MMU->timer[proc][(adr&0xF)>>2]; + + case 0x04000630 : + LOG("vect res\r\n"); /* TODO (clear): ??? */ + //execute = FALSE; + return 0; + case REG_POSTFLG : + return 1; + default : + break; + } + } + + /* Returns data from memory */ + return T1ReadWord(state->MMU->MMU_MEM[proc][(adr >> 20) & 0xFF], adr & state->MMU->MMU_MASK[proc][(adr >> 20) & 0xFF]); +} + +u32 FASTCALL MMU_read32(NDS_state *state, u32 proc, u32 adr) +{ +#ifdef INTERNAL_DTCM_READ + if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == state->MMU->DTCMRegion)) + { + /* Returns data from DTCM (ARM9 only) */ + return T1ReadLong(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF); + } +#endif + + // CFlash reading, Mic + if ((adr>=0x9000000)&&(adr<0x9900000)) + return (unsigned long)cflash_read(state, adr); + + adr &= 0x0FFFFFFF; + + if((adr >> 24) == 4) + { + /* Adress is an IO register */ + switch(adr) + { + // This is hacked due to the only current 3D core + case 0x04000600: + { + u32 fifonum = IPCFIFO+proc; + + u32 gxstat = (state->MMU->fifos[fifonum].empty<<26) | + (1<<25) | + (state->MMU->fifos[fifonum].full<<24) | + /*((NDS_nbpush[0]&1)<<13) | ((NDS_nbpush[2]&0x1F)<<8) |*/ + 2; + + LOG ("GXSTAT: 0x%X", gxstat); + + return gxstat; + } + + case 0x04000640: + case 0x04000644: + case 0x04000648: + case 0x0400064C: + case 0x04000650: + case 0x04000654: + case 0x04000658: + case 0x0400065C: + case 0x04000660: + case 0x04000664: + case 0x04000668: + case 0x0400066C: + case 0x04000670: + case 0x04000674: + case 0x04000678: + case 0x0400067C: + { + //LOG("4000640h..67Fh - CLIPMTX_RESULT - Read Current Clip Coordinates Matrix (R)"); +#if VIO2SF_GPU_ENABLE + return state->gpu3D->NDS_3D_GetClipMatrix (state->gpu3D, (adr-0x04000640)/4); +#else + return 0; +#endif + } + case 0x04000680: + case 0x04000684: + case 0x04000688: + case 0x0400068C: + case 0x04000690: + case 0x04000694: + case 0x04000698: + case 0x0400069C: + case 0x040006A0: + { +#if VIO2SF_GPU_ENABLE + //LOG("4000680h..6A3h - VECMTX_RESULT - Read Current Directional Vector Matrix (R)"); + return state->gpu3D->NDS_3D_GetDirectionalMatrix (state->gpu3D, (adr-0x04000680)/4); +#else + return 0; +#endif + } + + case 0x4000604: + { +#if VIO2SF_GPU_ENABLE + return (state->gpu3D->NDS_3D_GetNumPolys(state->gpu3D)&2047) & ((state->gpu3D->NDS_3D_GetNumVertex(state->gpu3D)&8191) << 16); + //LOG ("read32 - RAM_COUNT -> 0x%X", ((u32 *)(MMU->MMU_MEM[proc][(adr>>20)&0xFF]))[(adr&MMU->MMU_MASK[proc][(adr>>20)&0xFF])>>2]); +#else + return 0; +#endif + } + + case REG_IME : + return state->MMU->reg_IME[proc]; + case REG_IE : + return state->MMU->reg_IE[proc]; + case REG_IF : + return state->MMU->reg_IF[proc]; + case REG_IPCFIFORECV : + { + u16 IPCFIFO_CNT = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x184); + if(IPCFIFO_CNT&0x8000) + { + //execute = FALSE; + u32 fifonum = IPCFIFO+proc; + u32 val = FIFOValue(state->MMU->fifos + fifonum); + u32 remote = (proc+1) & 1; + u16 IPCFIFO_CNT_remote = T1ReadWord(state->MMU->MMU_MEM[remote][0x40], 0x184); + IPCFIFO_CNT |= (state->MMU->fifos[fifonum].empty<<8) | (state->MMU->fifos[fifonum].full<<9) | (state->MMU->fifos[fifonum].error<<14); + IPCFIFO_CNT_remote |= (state->MMU->fifos[fifonum].empty) | (state->MMU->fifos[fifonum].full<<1); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x184, IPCFIFO_CNT); + T1WriteWord(state->MMU->MMU_MEM[remote][0x40], 0x184, IPCFIFO_CNT_remote); + if ((state->MMU->fifos[fifonum].empty) && (IPCFIFO_CNT & BIT(2))) + NDS_makeInt(state, remote,17) ; /* remote: SEND FIFO EMPTY */ + return val; + } + } + return 0; + case REG_TM0CNTL : + case REG_TM1CNTL : + case REG_TM2CNTL : + case REG_TM3CNTL : + { + u32 val = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], (adr + 2) & 0xFFF); + return state->MMU->timer[proc][(adr&0xF)>>2] | (val<<16); + } + /* + case 0x04000640 : // TODO (clear): again, ??? + LOG("read proj\r\n"); + return 0; + case 0x04000680 : + LOG("read roat\r\n"); + return 0; + case 0x04000620 : + LOG("point res\r\n"); + return 0; + */ + case REG_GCDATAIN: + { + u32 val; + + if(!state->MMU->dscard[proc].adress) return 0; + + val = T1ReadLong(state->MMU->CART_ROM, state->MMU->dscard[proc].adress); + + state->MMU->dscard[proc].adress += 4; /* increment adress */ + + state->MMU->dscard[proc].transfer_count--; /* update transfer counter */ + if(state->MMU->dscard[proc].transfer_count) /* if transfer is not ended */ + { + return val; /* return data */ + } + else /* transfer is done */ + { + T1WriteLong(state->MMU->MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, T1ReadLong(state->MMU->MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff) & ~(0x00800000 | 0x80000000)); + /* = 0x7f7fffff */ + + /* if needed, throw irq for the end of transfer */ + if(T1ReadWord(state->MMU->MMU_MEM[proc][(REG_AUXSPICNT >> 20) & 0xff], REG_AUXSPICNT & 0xfff) & 0x4000) + { + if(proc == ARMCPU_ARM7) NDS_makeARM7Int(state, 19); + else NDS_makeARM9Int(state, 19); + } + + return val; + } + } + + default : + break; + } + } + + /* Returns data from memory */ + return T1ReadLong(state->MMU->MMU_MEM[proc][(adr >> 20) & 0xFF], adr & state->MMU->MMU_MASK[proc][(adr >> 20) & 0xFF]); +} + +void FASTCALL MMU_write8(NDS_state *state, u32 proc, u32 adr, u8 val) +{ +#ifdef INTERNAL_DTCM_WRITE + if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == state->MMU->DTCMRegion)) + { + /* Writes data in DTCM (ARM9 only) */ + state->ARM9Mem->ARM9_DTCM[adr&0x3FFF] = val; + return ; + } +#endif + + // CFlash writing, Mic + if ((adr>=0x9000000)&&(adr<0x9900000)) { + cflash_write(state,adr,val); + return; + } + + adr &= 0x0FFFFFFF; + + // This is bad, remove it + if(proc == ARMCPU_ARM7) + { + if ((adr>=0x04000400)&&(adr<0x0400051D)) + { + SPU_WriteByte(state, adr, val); + return; + } + } + + if (adr & 0xFF800000 == 0x04800000) + { + /* is wifi hardware, dont intermix with regular hardware registers */ + /* FIXME handle 8 bit writes */ + return ; + } + + switch(adr) + { + case REG_DISPA_WIN0H: + if(proc == ARMCPU_ARM9) GPU_setWIN0_H1 (state->MainScreen->gpu, val); + break ; + case REG_DISPA_WIN0H+1: + if(proc == ARMCPU_ARM9) GPU_setWIN0_H0 (state->MainScreen->gpu, val); + break ; + case REG_DISPA_WIN1H: + if(proc == ARMCPU_ARM9) GPU_setWIN1_H1 (state->MainScreen->gpu,val); + break ; + case REG_DISPA_WIN1H+1: + if(proc == ARMCPU_ARM9) GPU_setWIN1_H0 (state->MainScreen->gpu,val); + break ; + + case REG_DISPB_WIN0H: + if(proc == ARMCPU_ARM9) GPU_setWIN0_H1(state->SubScreen->gpu,val); + break ; + case REG_DISPB_WIN0H+1: + if(proc == ARMCPU_ARM9) GPU_setWIN0_H0(state->SubScreen->gpu,val); + break ; + case REG_DISPB_WIN1H: + if(proc == ARMCPU_ARM9) GPU_setWIN1_H1(state->SubScreen->gpu,val); + break ; + case REG_DISPB_WIN1H+1: + if(proc == ARMCPU_ARM9) GPU_setWIN1_H0(state->SubScreen->gpu,val); + break ; + + case REG_DISPA_WIN0V: + if(proc == ARMCPU_ARM9) GPU_setWIN0_V1(state->MainScreen->gpu,val) ; + break ; + case REG_DISPA_WIN0V+1: + if(proc == ARMCPU_ARM9) GPU_setWIN0_V0(state->MainScreen->gpu,val) ; + break ; + case REG_DISPA_WIN1V: + if(proc == ARMCPU_ARM9) GPU_setWIN1_V1(state->MainScreen->gpu,val) ; + break ; + case REG_DISPA_WIN1V+1: + if(proc == ARMCPU_ARM9) GPU_setWIN1_V0(state->MainScreen->gpu,val) ; + break ; + + case REG_DISPB_WIN0V: + if(proc == ARMCPU_ARM9) GPU_setWIN0_V1(state->SubScreen->gpu,val) ; + break ; + case REG_DISPB_WIN0V+1: + if(proc == ARMCPU_ARM9) GPU_setWIN0_V0(state->SubScreen->gpu,val) ; + break ; + case REG_DISPB_WIN1V: + if(proc == ARMCPU_ARM9) GPU_setWIN1_V1(state->SubScreen->gpu,val) ; + break ; + case REG_DISPB_WIN1V+1: + if(proc == ARMCPU_ARM9) GPU_setWIN1_V0(state->SubScreen->gpu,val) ; + break ; + + case REG_DISPA_WININ: + if(proc == ARMCPU_ARM9) GPU_setWININ0(state->MainScreen->gpu,val) ; + break ; + case REG_DISPA_WININ+1: + if(proc == ARMCPU_ARM9) GPU_setWININ1(state->MainScreen->gpu,val) ; + break ; + case REG_DISPA_WINOUT: + if(proc == ARMCPU_ARM9) GPU_setWINOUT(state->MainScreen->gpu,val) ; + break ; + case REG_DISPA_WINOUT+1: + if(proc == ARMCPU_ARM9) GPU_setWINOBJ(state->MainScreen->gpu,val); + break ; + + case REG_DISPB_WININ: + if(proc == ARMCPU_ARM9) GPU_setWININ0(state->SubScreen->gpu,val) ; + break ; + case REG_DISPB_WININ+1: + if(proc == ARMCPU_ARM9) GPU_setWININ1(state->SubScreen->gpu,val) ; + break ; + case REG_DISPB_WINOUT: + if(proc == ARMCPU_ARM9) GPU_setWINOUT(state->SubScreen->gpu,val) ; + break ; + case REG_DISPB_WINOUT+1: + if(proc == ARMCPU_ARM9) GPU_setWINOBJ(state->SubScreen->gpu,val) ; + break ; + + + case REG_DISPA_BLDCNT: + if(proc == ARMCPU_ARM9) GPU_setBLDCNT_HIGH(state->MainScreen->gpu,val); + break; + case REG_DISPA_BLDCNT+1: + if(proc == ARMCPU_ARM9) GPU_setBLDCNT_LOW (state->MainScreen->gpu,val); + break; + + case REG_DISPB_BLDCNT: + if(proc == ARMCPU_ARM9) GPU_setBLDCNT_HIGH (state->SubScreen->gpu,val); + break; + case REG_DISPB_BLDCNT+1: + if(proc == ARMCPU_ARM9) GPU_setBLDCNT_LOW (state->SubScreen->gpu,val); + break; + + case REG_DISPA_BLDALPHA: + if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVB(state->MainScreen->gpu,val) ; + break; + case REG_DISPA_BLDALPHA+1: + if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVA(state->MainScreen->gpu,val) ; + break; + + case REG_DISPB_BLDALPHA: + if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVB(state->SubScreen->gpu,val) ; + break; + case REG_DISPB_BLDALPHA+1: + if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVA(state->SubScreen->gpu,val); + break; + + case REG_DISPA_BLDY: + if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(state->MainScreen->gpu,val) ; + break ; + case REG_DISPB_BLDY: + if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(state->SubScreen->gpu,val) ; + break; + + /* TODO: EEEK ! Controls for VRAMs A, B, C, D are missing ! */ + /* TODO: Not all mappings of VRAMs are handled... (especially BG and OBJ modes) */ + case REG_VRAMCNTA: + case REG_VRAMCNTB: + case REG_VRAMCNTC: + case REG_VRAMCNTD: + if(proc == ARMCPU_ARM9) + { + MMU_VRAMWriteBackToLCD(state, 0) ; + MMU_VRAMWriteBackToLCD(state, 1) ; + MMU_VRAMWriteBackToLCD(state, 2) ; + MMU_VRAMWriteBackToLCD(state, 3) ; + switch(val & 0x1F) + { + case 1 : + state->MMU->vram_mode[adr-REG_VRAMCNTA] = 0; // BG-VRAM + //MMU->vram_offset[0] = ARM9Mem->ARM9_ABG+(0x20000*0); // BG-VRAM + break; + case 1 | (1 << 3) : + state->MMU->vram_mode[adr-REG_VRAMCNTA] = 1; // BG-VRAM + //MMU->vram_offset[0] = ARM9Mem->ARM9_ABG+(0x20000*1); // BG-VRAM + break; + case 1 | (2 << 3) : + state->MMU->vram_mode[adr-REG_VRAMCNTA] = 2; // BG-VRAM + //MMU->vram_offset[0] = ARM9Mem->ARM9_ABG+(0x20000*2); // BG-VRAM + break; + case 1 | (3 << 3) : + state->MMU->vram_mode[adr-REG_VRAMCNTA] = 3; // BG-VRAM + //MMU->vram_offset[0] = ARM9Mem->ARM9_ABG+(0x20000*3); // BG-VRAM + break; + case 0: /* mapped to lcd */ + state->MMU->vram_mode[adr-REG_VRAMCNTA] = 4 | (adr-REG_VRAMCNTA) ; + break ; + } + /* + * FIXME: simply texture slot handling + * This is a first stab and is not correct. It does + * not handle a VRAM texture slot becoming + * unconfigured. + * Revisit all of VRAM control handling for future + * release? + */ + if ( val & 0x80) { + if ( (val & 0x7) == 3) { + int slot_index = (val >> 3) & 0x3; + + state->ARM9Mem->textureSlotAddr[slot_index] = + &state->ARM9Mem->ARM9_LCD[0x20000 * (adr - REG_VRAMCNTA)]; + } + } + MMU_VRAMReloadFromLCD(state, adr-REG_VRAMCNTA,val) ; + } + break; + case REG_VRAMCNTE : + if(proc == ARMCPU_ARM9) + { + MMU_VRAMWriteBackToLCD(state, (u8)REG_VRAMCNTE) ; + if((val & 7) == 5) + { + state->ARM9Mem->ExtPal[0][0] = state->ARM9Mem->ARM9_LCD + 0x80000; + state->ARM9Mem->ExtPal[0][1] = state->ARM9Mem->ARM9_LCD + 0x82000; + state->ARM9Mem->ExtPal[0][2] = state->ARM9Mem->ARM9_LCD + 0x84000; + state->ARM9Mem->ExtPal[0][3] = state->ARM9Mem->ARM9_LCD + 0x86000; + } + else if((val & 7) == 3) + { + state->ARM9Mem->texPalSlot[0] = state->ARM9Mem->ARM9_LCD + 0x80000; + state->ARM9Mem->texPalSlot[1] = state->ARM9Mem->ARM9_LCD + 0x82000; + state->ARM9Mem->texPalSlot[2] = state->ARM9Mem->ARM9_LCD + 0x84000; + state->ARM9Mem->texPalSlot[3] = state->ARM9Mem->ARM9_LCD + 0x86000; + } + else if((val & 7) == 4) + { + state->ARM9Mem->ExtPal[0][0] = state->ARM9Mem->ARM9_LCD + 0x80000; + state->ARM9Mem->ExtPal[0][1] = state->ARM9Mem->ARM9_LCD + 0x82000; + state->ARM9Mem->ExtPal[0][2] = state->ARM9Mem->ARM9_LCD + 0x84000; + state->ARM9Mem->ExtPal[0][3] = state->ARM9Mem->ARM9_LCD + 0x86000; + } + + MMU_VRAMReloadFromLCD(state,adr-REG_VRAMCNTE,val) ; + } + break; + + case REG_VRAMCNTF : + if(proc == ARMCPU_ARM9) + { + switch(val & 0x1F) + { + case 4 : + state->ARM9Mem->ExtPal[0][0] = state->ARM9Mem->ARM9_LCD + 0x90000; + state->ARM9Mem->ExtPal[0][1] = state->ARM9Mem->ARM9_LCD + 0x92000; + break; + + case 4 | (1 << 3) : + state->ARM9Mem->ExtPal[0][2] = state->ARM9Mem->ARM9_LCD + 0x90000; + state->ARM9Mem->ExtPal[0][3] = state->ARM9Mem->ARM9_LCD + 0x92000; + break; + + case 3 : + state->ARM9Mem->texPalSlot[0] = state->ARM9Mem->ARM9_LCD + 0x90000; + break; + + case 3 | (1 << 3) : + state->ARM9Mem->texPalSlot[1] = state->ARM9Mem->ARM9_LCD + 0x90000; + break; + + case 3 | (2 << 3) : + state->ARM9Mem->texPalSlot[2] = state->ARM9Mem->ARM9_LCD + 0x90000; + break; + + case 3 | (3 << 3) : + state->ARM9Mem->texPalSlot[3] = state->ARM9Mem->ARM9_LCD + 0x90000; + break; + + case 5 : + case 5 | (1 << 3) : + case 5 | (2 << 3) : + case 5 | (3 << 3) : + state->ARM9Mem->ObjExtPal[0][0] = state->ARM9Mem->ARM9_LCD + 0x90000; + state->ARM9Mem->ObjExtPal[0][1] = state->ARM9Mem->ARM9_LCD + 0x92000; + break; + } + } + break; + case REG_VRAMCNTG : + if(proc == ARMCPU_ARM9) + { + switch(val & 0x1F) + { + case 4 : + state->ARM9Mem->ExtPal[0][0] = state->ARM9Mem->ARM9_LCD + 0x94000; + state->ARM9Mem->ExtPal[0][1] = state->ARM9Mem->ARM9_LCD + 0x96000; + break; + + case 4 | (1 << 3) : + state->ARM9Mem->ExtPal[0][2] = state->ARM9Mem->ARM9_LCD + 0x94000; + state->ARM9Mem->ExtPal[0][3] = state->ARM9Mem->ARM9_LCD + 0x96000; + break; + + case 3 : + state->ARM9Mem->texPalSlot[0] = state->ARM9Mem->ARM9_LCD + 0x94000; + break; + + case 3 | (1 << 3) : + state->ARM9Mem->texPalSlot[1] = state->ARM9Mem->ARM9_LCD + 0x94000; + break; + + case 3 | (2 << 3) : + state->ARM9Mem->texPalSlot[2] = state->ARM9Mem->ARM9_LCD + 0x94000; + break; + + case 3 | (3 << 3) : + state->ARM9Mem->texPalSlot[3] = state->ARM9Mem->ARM9_LCD + 0x94000; + break; + + case 5 : + case 5 | (1 << 3) : + case 5 | (2 << 3) : + case 5 | (3 << 3) : + state->ARM9Mem->ObjExtPal[0][0] = state->ARM9Mem->ARM9_LCD + 0x94000; + state->ARM9Mem->ObjExtPal[0][1] = state->ARM9Mem->ARM9_LCD + 0x96000; + break; + } + } + break; + + case REG_VRAMCNTH : + if(proc == ARMCPU_ARM9) + { + MMU_VRAMWriteBackToLCD(state, (u8)REG_VRAMCNTH) ; + + if((val & 7) == 2) + { + state->ARM9Mem->ExtPal[1][0] = state->ARM9Mem->ARM9_LCD + 0x98000; + state->ARM9Mem->ExtPal[1][1] = state->ARM9Mem->ARM9_LCD + 0x9A000; + state->ARM9Mem->ExtPal[1][2] = state->ARM9Mem->ARM9_LCD + 0x9C000; + state->ARM9Mem->ExtPal[1][3] = state->ARM9Mem->ARM9_LCD + 0x9E000; + } + + MMU_VRAMReloadFromLCD(state,adr-REG_VRAMCNTH,val) ; + } + break; + + case REG_VRAMCNTI : + if(proc == ARMCPU_ARM9) + { + MMU_VRAMWriteBackToLCD(state,(u8)REG_VRAMCNTI) ; + + if((val & 7) == 3) + { + state->ARM9Mem->ObjExtPal[1][0] = state->ARM9Mem->ARM9_LCD + 0xA0000; + state->ARM9Mem->ObjExtPal[1][1] = state->ARM9Mem->ARM9_LCD + 0xA2000; + } + + MMU_VRAMReloadFromLCD(state,adr-REG_VRAMCNTI,val) ; + } + break; + +#ifdef LOG_CARD + case 0x040001A0 : /* TODO (clear): ??? */ + case 0x040001A1 : + case 0x040001A2 : + case 0x040001A8 : + case 0x040001A9 : + case 0x040001AA : + case 0x040001AB : + case 0x040001AC : + case 0x040001AD : + case 0x040001AE : + case 0x040001AF : + LOG("%08X : %02X\r\n", adr, val); +#endif + + default : + break; + } + + state->MMU->MMU_MEM[proc][(adr>>20)&0xFF][adr&state->MMU->MMU_MASK[proc][(adr>>20)&0xFF]]=val; +} + +void FASTCALL MMU_write16(NDS_state *state, u32 proc, u32 adr, u16 val) +{ +#ifdef INTERNAL_DTCM_WRITE + if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == state->MMU->DTCMRegion)) + { + /* Writes in DTCM (ARM9 only) */ + T1WriteWord(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF, val); + return; + } +#endif + + // CFlash writing, Mic + if ((adr>=0x08800000)&&(adr<0x09900000)) + { + cflash_write(state,adr,val); + return; + } + +#ifdef EXPERIMENTAL_WIFI + + /* wifi mac access */ + if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000)) + { + WIFI_write16(&state->wifiMac,adr,val) ; + return ; + } +#else + if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000)) + return ; +#endif + + adr &= 0x0FFFFFFF; + + // This is bad, remove it + if(proc == ARMCPU_ARM7) + { + if ((adr>=0x04000400)&&(adr<0x0400051D)) + { + SPU_WriteWord(state, adr, val); + return; + } + } + + if((adr >> 24) == 4) + { + /* Adress is an IO register */ + switch(adr) + { +#if VIO2SF_GPU_ENABLE + case 0x0400035C: + { + ((u16 *)(state->MMU->MMU_MEM[proc][0x40]))[0x35C>>1] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_FogOffset (state->gpu3D, val); + } + return; + } + case 0x04000340: + { + ((u16 *)(state->MMU->MMU_MEM[proc][0x40]))[0x340>>1] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_AlphaFunc(state->gpu3D, val); + } + return; + } + case 0x04000060: + { + ((u16 *)(state->MMU->MMU_MEM[proc][0x40]))[0x060>>1] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Control(state->gpu3D, val); + } + return; + } + case 0x04000354: + { + ((u16 *)(state->MMU->MMU_MEM[proc][0x40]))[0x354>>1] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_ClearDepth(state->gpu3D, val); + } + return; + } +#endif + + case REG_DISPA_BLDCNT: + if(proc == ARMCPU_ARM9) GPU_setBLDCNT(state->MainScreen->gpu,val) ; + break ; + case REG_DISPB_BLDCNT: + if(proc == ARMCPU_ARM9) GPU_setBLDCNT(state->SubScreen->gpu,val) ; + break ; + case REG_DISPA_BLDALPHA: + if(proc == ARMCPU_ARM9) GPU_setBLDALPHA(state->MainScreen->gpu,val) ; + break ; + case REG_DISPB_BLDALPHA: + if(proc == ARMCPU_ARM9) GPU_setBLDALPHA(state->SubScreen->gpu,val) ; + break ; + case REG_DISPA_BLDY: + if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(state->MainScreen->gpu,val) ; + break ; + case REG_DISPB_BLDY: + if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(state->SubScreen->gpu,val) ; + break; + case REG_DISPA_MASTERBRIGHT: + GPU_setMasterBrightness (state->MainScreen->gpu, val); + break; + /* + case REG_DISPA_MOSAIC: + if(proc == ARMCPU_ARM9) GPU_setMOSAIC(state->MainScreen->gpu,val) ; + break ; + case REG_DISPB_MOSAIC: + if(proc == ARMCPU_ARM9) GPU_setMOSAIC(state->SubScreen->gpu,val) ; + break ; + */ + + case REG_DISPA_WIN0H: + if(proc == ARMCPU_ARM9) GPU_setWIN0_H (state->MainScreen->gpu,val) ; + break ; + case REG_DISPA_WIN1H: + if(proc == ARMCPU_ARM9) GPU_setWIN1_H(state->MainScreen->gpu,val) ; + break ; + case REG_DISPB_WIN0H: + if(proc == ARMCPU_ARM9) GPU_setWIN0_H(state->SubScreen->gpu,val) ; + break ; + case REG_DISPB_WIN1H: + if(proc == ARMCPU_ARM9) GPU_setWIN1_H(state->SubScreen->gpu,val) ; + break ; + case REG_DISPA_WIN0V: + if(proc == ARMCPU_ARM9) GPU_setWIN0_V(state->MainScreen->gpu,val) ; + break ; + case REG_DISPA_WIN1V: + if(proc == ARMCPU_ARM9) GPU_setWIN1_V(state->MainScreen->gpu,val) ; + break ; + case REG_DISPB_WIN0V: + if(proc == ARMCPU_ARM9) GPU_setWIN0_V(state->SubScreen->gpu,val) ; + break ; + case REG_DISPB_WIN1V: + if(proc == ARMCPU_ARM9) GPU_setWIN1_V(state->SubScreen->gpu,val) ; + break ; + case REG_DISPA_WININ: + if(proc == ARMCPU_ARM9) GPU_setWININ(state->MainScreen->gpu, val) ; + break ; + case REG_DISPA_WINOUT: + if(proc == ARMCPU_ARM9) GPU_setWINOUT16(state->MainScreen->gpu, val) ; + break ; + case REG_DISPB_WININ: + if(proc == ARMCPU_ARM9) GPU_setWININ(state->SubScreen->gpu, val) ; + break ; + case REG_DISPB_WINOUT: + if(proc == ARMCPU_ARM9) GPU_setWINOUT16(state->SubScreen->gpu, val) ; + break ; + + case REG_DISPB_MASTERBRIGHT: + GPU_setMasterBrightness (state->SubScreen->gpu, val); + break; + + case REG_POWCNT1 : + if(proc == ARMCPU_ARM9) + { + if(val & (1<<15)) + { + LOG("Main core on top\n"); + state->MainScreen->offset = 0; + state->SubScreen->offset = 192; + //nds->swapScreen(); + } + else + { + LOG("Main core on bottom (%04X)\n", val); + state->MainScreen->offset = 192; + state->SubScreen->offset = 0; + } + } + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x304, val); + return; + + case REG_AUXSPICNT: + T1WriteWord(state->MMU->MMU_MEM[proc][(REG_AUXSPICNT >> 20) & 0xff], REG_AUXSPICNT & 0xfff, val); + state->AUX_SPI_CNT = val; + + if (val == 0) + mc_reset_com(&state->MMU->bupmem); /* reset backup memory device communication */ + return; + + case REG_AUXSPIDATA: + if(val!=0) + { + state->AUX_SPI_CMD = val & 0xFF; + } + + T1WriteWord(state->MMU->MMU_MEM[proc][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&state->MMU->bupmem, val)); + return; + + case REG_SPICNT : + if(proc == ARMCPU_ARM7) + { + int reset_firmware = 1; + + if ( ((state->SPI_CNT >> 8) & 0x3) == 1) { + if ( ((val >> 8) & 0x3) == 1) { + if ( BIT11(state->SPI_CNT)) { + /* select held */ + reset_firmware = 0; + } + } + } + + //MMU->fw.com == 0; /* reset fw device communication */ + if ( reset_firmware) { + /* reset fw device communication */ + mc_reset_com(&state->MMU->fw); + } + state->SPI_CNT = val; + } + + T1WriteWord(state->MMU->MMU_MEM[proc][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff, val); + return; + + case REG_SPIDATA : + if(proc==ARMCPU_ARM7) + { + u16 spicnt; + + if(val!=0) + { + state->SPI_CMD = val; + } + + spicnt = T1ReadWord(state->MMU->MMU_MEM[proc][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff); + + switch((spicnt >> 8) & 0x3) + { + case 0 : + break; + + case 1 : /* firmware memory device */ + if(spicnt & 0x3 != 0) /* check SPI baudrate (must be 4mhz) */ + { + T1WriteWord(state->MMU->MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, 0); + break; + } + T1WriteWord(state->MMU->MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&state->MMU->fw, val)); + + return; + + case 2 : + switch(state->SPI_CMD & 0x70) + { + case 0x00 : + val = 0; + break; + case 0x10 : + //execute = FALSE; + if(state->SPI_CNT&(1<<11)) + { + if(state->partie) + { + val = ((state->nds->touchY<<3)&0x7FF); + state->partie = 0; + //execute = FALSE; + break; + } + val = (state->nds->touchY>>5); + state->partie = 1; + break; + } + val = ((state->nds->touchY<<3)&0x7FF); + state->partie = 1; + break; + case 0x20 : + val = 0; + break; + case 0x30 : + val = 0; + break; + case 0x40 : + val = 0; + break; + case 0x50 : + if(spicnt & 0x800) + { + if(state->partie) + { + val = ((state->nds->touchX<<3)&0x7FF); + state->partie = 0; + break; + } + val = (state->nds->touchX>>5); + state->partie = 1; + break; + } + val = ((state->nds->touchX<<3)&0x7FF); + state->partie = 1; + break; + case 0x60 : + val = 0; + break; + case 0x70 : + val = 0; + break; + } + break; + + case 3 : + /* NOTICE: Device 3 of SPI is reserved (unused and unusable) */ + break; + } + } + + T1WriteWord(state->MMU->MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, val); + return; + + /* NOTICE: Perhaps we have to use gbatek-like reg names instead of libnds-like ones ...*/ + + case REG_DISPA_BG0CNT : + //GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val); + if(proc == ARMCPU_ARM9) GPU_setBGProp(state->MainScreen->gpu, 0, val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x8, val); + return; + case REG_DISPA_BG1CNT : + //GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val); + if(proc == ARMCPU_ARM9) GPU_setBGProp(state->MainScreen->gpu, 1, val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0xA, val); + return; + case REG_DISPA_BG2CNT : + //GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val); + if(proc == ARMCPU_ARM9) GPU_setBGProp(state->MainScreen->gpu, 2, val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0xC, val); + return; + case REG_DISPA_BG3CNT : + //GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val); + if(proc == ARMCPU_ARM9) GPU_setBGProp(state->MainScreen->gpu, 3, val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0xE, val); + return; + case REG_DISPB_BG0CNT : + //GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val); + if(proc == ARMCPU_ARM9) GPU_setBGProp(state->SubScreen->gpu, 0, val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x1008, val); + return; + case REG_DISPB_BG1CNT : + //GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val); + if(proc == ARMCPU_ARM9) GPU_setBGProp(state->SubScreen->gpu, 1, val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x100A, val); + return; + case REG_DISPB_BG2CNT : + //GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val); + if(proc == ARMCPU_ARM9) GPU_setBGProp(state->SubScreen->gpu, 2, val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x100C, val); + return; + case REG_DISPB_BG3CNT : + //GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val); + if(proc == ARMCPU_ARM9) GPU_setBGProp(state->SubScreen->gpu, 3, val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x100E, val); + return; + case REG_IME : { + u32 old_val = state->MMU->reg_IME[proc]; + u32 new_val = val & 1; + state->MMU->reg_IME[proc] = new_val; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x208, val); + if ( new_val && old_val != new_val) { + /* raise an interrupt request to the CPU if needed */ + if ( state->MMU->reg_IE[proc] & state->MMU->reg_IF[proc]) { + state->NDS_ARM7->wIRQ = TRUE; + state->NDS_ARM7->waitIRQ = FALSE; + } + } + return; + } + case REG_VRAMCNTA: + MMU_write8(state,proc,adr,val & 0xFF) ; + MMU_write8(state,proc,adr+1,val >> 8) ; + return ; + case REG_VRAMCNTC: + MMU_write8(state,proc,adr,val & 0xFF) ; + MMU_write8(state,proc,adr+1,val >> 8) ; + return ; + case REG_VRAMCNTE: + MMU_write8(state,proc,adr,val & 0xFF) ; + MMU_write8(state,proc,adr+1,val >> 8) ; + return ; + case REG_VRAMCNTG: + MMU_write8(state,proc,adr,val & 0xFF) ; + MMU_write8(state,proc,adr+1,val >> 8) ; + return ; + case REG_VRAMCNTI: + MMU_write8(state,proc,adr,val & 0xFF) ; + return ; + + case REG_IE : + state->MMU->reg_IE[proc] = (state->MMU->reg_IE[proc]&0xFFFF0000) | val; + if ( state->MMU->reg_IME[proc]) { + /* raise an interrupt request to the CPU if needed */ + if ( state->MMU->reg_IE[proc] & state->MMU->reg_IF[proc]) { + state->NDS_ARM7->wIRQ = TRUE; + state->NDS_ARM7->waitIRQ = FALSE; + } + } + return; + case REG_IE + 2 : + state->execute = FALSE; + state->MMU->reg_IE[proc] = (state->MMU->reg_IE[proc]&0xFFFF) | (((u32)val)<<16); + return; + + case REG_IF : + state->execute = FALSE; + state->MMU->reg_IF[proc] &= (~((u32)val)); + return; + case REG_IF + 2 : + state->execute = FALSE; + state->MMU->reg_IF[proc] &= (~(((u32)val)<<16)); + return; + + case REG_IPCSYNC : + { + u32 remote = (proc+1)&1; + u16 IPCSYNC_remote = T1ReadWord(state->MMU->MMU_MEM[remote][0x40], 0x180); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF)); + T1WriteWord(state->MMU->MMU_MEM[remote][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF)); + state->MMU->reg_IF[remote] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU->reg_IME[remote] << 16);// & (MMU->reg_IE[remote] & (1<<16));// + //execute = FALSE; + } + return; + case REG_IPCFIFOCNT : + { + u32 cnt_l = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x184) ; + u32 cnt_r = T1ReadWord(state->MMU->MMU_MEM[(proc+1) & 1][0x40], 0x184) ; + if ((val & 0x8000) && !(cnt_l & 0x8000)) + { + /* this is the first init, the other side didnt init yet */ + /* so do a complete init */ + FIFOInit(state->MMU->fifos + (IPCFIFO+proc)); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x184,0x8101) ; + /* and then handle it as usual */ + } + + if(val & 0x4008) + { + FIFOInit(state->MMU->fifos + (IPCFIFO+((proc+1)&1))); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1); + T1WriteWord(state->MMU->MMU_MEM[proc^1][0x40], 0x184, (cnt_r & 0xC507) | 0x100); + state->MMU->reg_IF[proc] |= ((val & 4)<<15);// & (MMU->reg_IME[proc]<<17);// & (MMU->reg_IE[proc]&0x20000);// + return; + } + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x184, T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x184) | (val & 0xBFF4)); + } + return; + case REG_TM0CNTL : + case REG_TM1CNTL : + case REG_TM2CNTL : + case REG_TM3CNTL : + state->MMU->timerReload[proc][(adr>>2)&3] = val; + return; + case REG_TM0CNTH : + case REG_TM1CNTH : + case REG_TM2CNTH : + case REG_TM3CNTH : + if(val&0x80) + { + state->MMU->timer[proc][((adr-2)>>2)&0x3] = state->MMU->timerReload[proc][((adr-2)>>2)&0x3]; + } + state->MMU->timerON[proc][((adr-2)>>2)&0x3] = val & 0x80; + switch(val&7) + { + case 0 : + state->MMU->timerMODE[proc][((adr-2)>>2)&0x3] = 0+1;//proc; + break; + case 1 : + state->MMU->timerMODE[proc][((adr-2)>>2)&0x3] = 6+1;//proc; + break; + case 2 : + state->MMU->timerMODE[proc][((adr-2)>>2)&0x3] = 8+1;//proc; + break; + case 3 : + state->MMU->timerMODE[proc][((adr-2)>>2)&0x3] = 10+1;//proc; + break; + default : + state->MMU->timerMODE[proc][((adr-2)>>2)&0x3] = 0xFFFF; + break; + } + if(!(val & 0x80)) + state->MMU->timerRUN[proc][((adr-2)>>2)&0x3] = FALSE; + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], adr & 0xFFF, val); + return; + case REG_DISPA_DISPCNT+2 : + { + //execute = FALSE; + u32 v = (T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0) & 0xFFFF) | ((u32) val << 16); + GPU_setVideoProp(state->MainScreen->gpu, v); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0, v); + } + return; + case REG_DISPA_DISPCNT : + if(proc == ARMCPU_ARM9) + { + u32 v = (T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0) & 0xFFFF0000) | val; + GPU_setVideoProp(state->MainScreen->gpu, v); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0, v); + } + return; + case REG_DISPA_DISPCAPCNT : + if(proc == ARMCPU_ARM9) + { + GPU_set_DISPCAPCNT(state->MainScreen->gpu,val); + } + return; + case REG_DISPB_DISPCNT+2 : + if(proc == ARMCPU_ARM9) + { + //execute = FALSE; + u32 v = (T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0x1000) & 0xFFFF) | ((u32) val << 16); + GPU_setVideoProp(state->SubScreen->gpu, v); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x1000, v); + } + return; + case REG_DISPB_DISPCNT : + { + u32 v = (T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0x1000) & 0xFFFF0000) | val; + GPU_setVideoProp(state->SubScreen->gpu, v); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x1000, v); + } + return; + //case 0x020D8460 : + /*case 0x0235A904 : + LOG("ECRIRE %d %04X\r\n", proc, val); + execute = FALSE;*/ + case REG_DMA0CNTH : + { + u32 v; + + //if(val&0x8000) execute = FALSE; + //LOG("16 bit dma0 %04X\r\n", val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0xBA, val); + state->DMASrc[proc][0] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xB0); + state->DMADst[proc][0] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xB4); + v = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xB8); + state->MMU->DMAStartTime[proc][0] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7); + state->MMU->DMACrt[proc][0] = v; + if(state->MMU->DMAStartTime[proc][0] == 0) + MMU_doDMA(state, proc, 0); + #ifdef LOG_DMA2 + //else + { + LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 0, state->DMASrc[proc][0], state->DMADst[proc][0], (val&(1<<25))?"ON":"OFF"); + } + #endif + } + return; + case REG_DMA1CNTH : + { + u32 v; + //if(val&0x8000) execute = FALSE; + //LOG("16 bit dma1 %04X\r\n", val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0xC6, val); + state->DMASrc[proc][1] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xBC); + state->DMADst[proc][1] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xC0); + v = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xC4); + state->MMU->DMAStartTime[proc][1] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7); + state->MMU->DMACrt[proc][1] = v; + if(state->MMU->DMAStartTime[proc][1] == 0) + MMU_doDMA(state, proc, 1); + #ifdef LOG_DMA2 + //else + { + LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 1, state->DMASrc[proc][1], state->DMADst[proc][1], (val&(1<<25))?"ON":"OFF"); + } + #endif + } + return; + case REG_DMA2CNTH : + { + u32 v; + //if(val&0x8000) execute = FALSE; + //LOG("16 bit dma2 %04X\r\n", val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0xD2, val); + state->DMASrc[proc][2] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xC8); + state->DMADst[proc][2] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xCC); + v = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xD0); + state->MMU->DMAStartTime[proc][2] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7); + state->MMU->DMACrt[proc][2] = v; + if(state->MMU->DMAStartTime[proc][2] == 0) + MMU_doDMA(state, proc, 2); + #ifdef LOG_DMA2 + //else + { + LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 2, state->DMASrc[proc][2], state->DMADst[proc][2], (val&(1<<25))?"ON":"OFF"); + } + #endif + } + return; + case REG_DMA3CNTH : + { + u32 v; + //if(val&0x8000) execute = FALSE; + //LOG("16 bit dma3 %04X\r\n", val); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0xDE, val); + state->DMASrc[proc][3] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xD4); + state->DMADst[proc][3] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xD8); + v = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xDC); + state->MMU->DMAStartTime[proc][3] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7); + state->MMU->DMACrt[proc][3] = v; + + if(state->MMU->DMAStartTime[proc][3] == 0) + MMU_doDMA(state, proc, 3); + #ifdef LOG_DMA2 + //else + { + LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 3, state->DMASrc[proc][3], state->DMADst[proc][3], (val&(1<<25))?"ON":"OFF"); + } + #endif + } + return; + //case REG_AUXSPICNT : execute = FALSE; + default : + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], adr&state->MMU->MMU_MASK[proc][(adr>>20)&0xFF], val); + return; + } + } + T1WriteWord(state->MMU->MMU_MEM[proc][(adr>>20)&0xFF], adr&state->MMU->MMU_MASK[proc][(adr>>20)&0xFF], val); +} + + +void FASTCALL MMU_write32(NDS_state *state, u32 proc, u32 adr, u32 val) +{ +#ifdef INTERNAL_DTCM_WRITE + if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==state->MMU->DTCMRegion)) + { + T1WriteLong(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF, val); + return ; + } +#endif + + // CFlash writing, Mic + if ((adr>=0x9000000)&&(adr<0x9900000)) { + cflash_write(state,adr,val); + return; + } + + adr &= 0x0FFFFFFF; + + // This is bad, remove it + if(proc == ARMCPU_ARM7) + { + if ((adr>=0x04000400)&&(adr<0x0400051D)) + { + SPU_WriteLong(state, adr, val); + return; + } + } + + if (adr & 0xFF800000 == 0x04800000) { + /* access to non regular hw registers */ + /* return to not overwrite valid data */ + return ; + } ; + + + if((adr>>24)==4) + { + if (adr >= 0x04000400 && adr < 0x04000440) + { + // Geometry commands (aka Dislay Lists) - Parameters:X + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x400>>2] = val; +#if VIO2SF_GPU_ENABLE + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_CallList(state->gpu3D, val); + } +#endif + } + else + switch(adr) + { +#if VIO2SF_GPU_ENABLE + // Alpha test reference value - Parameters:1 + case 0x04000340: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x340>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_AlphaFunc(state->gpu3D, val); + } + return; + } + // Clear background color setup - Parameters:2 + case 0x04000350: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x350>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_ClearColor(state->gpu3D, val); + } + return; + } + // Clear background depth setup - Parameters:2 + case 0x04000354: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x354>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_ClearDepth(state->gpu3D, val); + } + return; + } + // Fog Color - Parameters:4b + case 0x04000358: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x358>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_FogColor(state->gpu3D, val); + } + return; + } + case 0x0400035C: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x35C>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_FogOffset(state->gpu3D, val); + } + return; + } + // Matrix mode - Parameters:1 + case 0x04000440: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x440>>2] = val; + + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_MatrixMode(state->gpu3D, val); + } + return; + } + // Push matrix - Parameters:0 + case 0x04000444: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x444>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_PushMatrix(state->gpu3D); + } + return; + } + // Pop matrix/es - Parameters:1 + case 0x04000448: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x448>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_PopMatrix(state->gpu3D, val); + } + return; + } + // Store matrix in the stack - Parameters:1 + case 0x0400044C: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x44C>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_StoreMatrix(state->gpu3D, val); + } + return; + } + // Restore matrix from the stack - Parameters:1 + case 0x04000450: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x450>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_RestoreMatrix(state->gpu3D, val); + } + return; + } + // Load Identity matrix - Parameters:0 + case 0x04000454: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x454>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_LoadIdentity(state->gpu3D); + } + return; + } + // Load 4x4 matrix - Parameters:16 + case 0x04000458: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x458>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_LoadMatrix4x4(state->gpu3D, val); + } + return; + } + // Load 4x3 matrix - Parameters:12 + case 0x0400045C: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x45C>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_LoadMatrix4x3(state->gpu3D, val); + } + return; + } + // Multiply 4x4 matrix - Parameters:16 + case 0x04000460: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x460>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_MultMatrix4x4(state->gpu3D, val); + } + return; + } + // Multiply 4x4 matrix - Parameters:12 + case 0x04000464: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x464>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_MultMatrix4x3(state->gpu3D, val); + } + return; + } + // Multiply 3x3 matrix - Parameters:9 + case 0x04000468 : + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x468>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_MultMatrix3x3(state->gpu3D, val); + } + return; + } + // Multiply current matrix by scaling matrix - Parameters:3 + case 0x0400046C: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x46C>>2] = val; + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Scale(state->gpu3D, val); + } + return; + } + // Multiply current matrix by translation matrix - Parameters:3 + case 0x04000470: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x470>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Translate(state->gpu3D, val); + } + return; + } + // Set vertex color - Parameters:1 + case 0x04000480: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x480>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Color3b(state->gpu3D, val); + } + return; + } + // Set vertex normal - Parameters:1 + case 0x04000484: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x484>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Normal(state->gpu3D, val); + } + return; + } + // Set vertex texture coordinate - Parameters:1 + case 0x04000488: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x488>>2] = val; + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_TexCoord(state->gpu3D, val); + } + return; + } + // Set vertex position 16b/coordinate - Parameters:2 + case 0x0400048C: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x48C>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Vertex16b(state->gpu3D, val); + } + return; + } + // Set vertex position 10b/coordinate - Parameters:1 + case 0x04000490: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x490>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Vertex10b(state->gpu3D, val); + } + return; + } + // Set vertex XY position - Parameters:1 + case 0x04000494: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x494>>2] = val; + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Vertex3_cord(state->gpu3D,0,1,val); + } + return; + } + // Set vertex XZ position - Parameters:1 + case 0x04000498: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x498>>2] = val; + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Vertex3_cord(state->gpu3D,0,2,val); + } + return; + } + // Set vertex YZ position - Parameters:1 + case 0x0400049C: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x49C>>2] = val; + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Vertex3_cord(state->gpu3D,1,2,val); + } + return; + } + // Set vertex difference position (offset from the last vertex) - Parameters:1 + case 0x040004A0: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4A0>>2] = val; + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Vertex_rel (state->gpu3D,val); + } + return; + } + // Set polygon attributes - Parameters:1 + case 0x040004A4: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4A4>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_PolygonAttrib(state->gpu3D,val); + } + return; + } + // Set texture parameteres - Parameters:1 + case 0x040004A8: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4A8>>2] = val; + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_TexImage(state->gpu3D,val); + } + return; + } + // Set palette base address - Parameters:1 + case 0x040004AC: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4AC>>2] = val&0x1FFF; + if(proc==ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_TexPalette(state->gpu3D, val&0x1FFFF); + } + return; + } + // Set material diffuse/ambient parameters - Parameters:1 + case 0x040004C0: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4C0>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Material0 (state->gpu3D, val); + } + return; + } + // Set material reflection/emission parameters - Parameters:1 + case 0x040004C4: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4C4>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Material1 (state->gpu3D, val); + } + return; + } + // Light direction vector - Parameters:1 + case 0x040004C8: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4C8>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_LightDirection (state->gpu3D, val); + } + return; + } + // Light color - Parameters:1 + case 0x040004CC: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4CC>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_LightColor(state->gpu3D, val); + } + return; + } + // Material Shininess - Parameters:32 + case 0x040004D0: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x4D0>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Shininess(state->gpu3D, val); + } + return; + } + // Begin vertex list - Parameters:1 + case 0x04000500: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x500>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Begin(state->gpu3D, val); + } + return; + } + // End vertex list - Parameters:0 + case 0x04000504: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x504>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_End(state->gpu3D); + } + return; + } + // Swap rendering engine buffers - Parameters:1 + case 0x04000540: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x540>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_Flush(state->gpu3D, val); + } + return; + } + // Set viewport coordinates - Parameters:1 + case 0x04000580: + { + ((u32 *)(state->MMU->MMU_MEM[proc][0x40]))[0x580>>2] = val; + if(proc == ARMCPU_ARM9) + { + state->gpu3D->NDS_3D_ViewPort(state->gpu3D, val); + } + return; + } +#endif + + case REG_DISPA_WININ: + { + if(proc == ARMCPU_ARM9) + { + GPU_setWININ (state->MainScreen->gpu, val & 0xFFFF) ; + GPU_setWINOUT16 (state->MainScreen->gpu, (val >> 16) & 0xFFFF) ; + } + break; + } + case REG_DISPB_WININ: + { + if(proc == ARMCPU_ARM9) + { + GPU_setWININ (state->SubScreen->gpu, val & 0xFFFF) ; + GPU_setWINOUT16 (state->SubScreen->gpu, (val >> 16) & 0xFFFF) ; + } + break; + } + + case REG_DISPA_BLDCNT: + { + if (proc == ARMCPU_ARM9) + { + GPU_setBLDCNT (state->MainScreen->gpu,val&0xffff); + GPU_setBLDALPHA (state->MainScreen->gpu,val>>16); + } + break; + } + case REG_DISPB_BLDCNT: + { + if (proc == ARMCPU_ARM9) + { + GPU_setBLDCNT (state->SubScreen->gpu,val&0xffff); + GPU_setBLDALPHA (state->SubScreen->gpu,val>>16); + } + break; + } +/* + // Commented out, as this doesn't use the plug-in system, neither works + case cmd_3D_MTX_MODE // 0x04000440 : + if (proc == ARMCPU_ARM9) gl_MTX_MODE(val); + return; + case cmd_3D_MTX_PUSH // 0x04000444 : + case cmd_3D_MTX_POP // 0x04000448 : + case cmd_3D_MTX_STORE // 0x0400044C : + case cmd_3D_MTX_RESTORE // 0x04000450 : + if (proc == ARMCPU_ARM9) gl_print_cmd(adr); + return; + case cmd_3D_MTX_IDENTITY // 0x04000454 : + if (proc == ARMCPU_ARM9) gl_MTX_IDENTITY(); + return; + case cmd_3D_MTX_LOAD_4x4 // 0x04000458 : + if (proc == ARMCPU_ARM9) gl_MTX_LOAD_4x4(val); + return; + case cmd_3D_MTX_LOAD_4x3 // 0x0400045C : + if (proc == ARMCPU_ARM9) gl_MTX_LOAD_4x3(val); + return; + case cmd_3D_MTX_MULT_4x4 // 0x04000460 : + if (proc == ARMCPU_ARM9) gl_MTX_MULT_4x4(val); + return; + case cmd_3D_MTX_MULT_4x3 // 0x04000464 : + if (proc == ARMCPU_ARM9) gl_MTX_MULT_4x3(val); + return; + case cmd_3D_MTX_MULT_3x3 // 0x04000468 : + if (proc == ARMCPU_ARM9) gl_MTX_MULT_3x3(val); + return; + case cmd_3D_MTX_SCALE // 0x0400046C : + case cmd_3D_MTX_TRANS // 0x04000470 : + case cmd_3D_COLOR // 0x04000480 : + case cmd_3D_NORMA // 0x04000484 : + if (proc == ARMCPU_ARM9) gl_print_cmd(adr); + return; + case cmd_3D_TEXCOORD // 0x04000488 : + if (proc == ARMCPU_ARM9) gl_TEXCOORD(val); + return; + case cmd_3D_VTX_16 // 0x0400048C : + if (proc == ARMCPU_ARM9) gl_VTX_16(val); + return; + case cmd_3D_VTX_10 // 0x04000490 : + if (proc == ARMCPU_ARM9) gl_VTX_10(val); + return; + case cmd_3D_VTX_XY // 0x04000494 : + if (proc == ARMCPU_ARM9) gl_VTX_XY(val); + return; + case cmd_3D_VTX_XZ // 0x04000498 : + if (proc == ARMCPU_ARM9) gl_VTX_XZ(val); + return; + case cmd_3D_VTX_YZ // 0x0400049C : + if (proc == ARMCPU_ARM9) gl_VTX_YZ(val); + return; + case cmd_3D_VTX_DIFF // 0x040004A0 : + if (proc == ARMCPU_ARM9) gl_VTX_DIFF(val); + return; + case cmd_3D_POLYGON_ATTR // 0x040004A4 : + case cmd_3D_TEXIMAGE_PARAM // 0x040004A8 : + case cmd_3D_PLTT_BASE // 0x040004AC : + case cmd_3D_DIF_AMB // 0x040004C0 : + case cmd_3D_SPE_EMI // 0x040004C4 : + case cmd_3D_LIGHT_VECTOR // 0x040004C8 : + case cmd_3D_LIGHT_COLOR // 0x040004CC : + case cmd_3D_SHININESS // 0x040004D0 : + if (proc == ARMCPU_ARM9) gl_print_cmd(adr); + return; + case cmd_3D_BEGIN_VTXS // 0x04000500 : + if (proc == ARMCPU_ARM9) gl_VTX_begin(val); + return; + case cmd_3D_END_VTXS // 0x04000504 : + if (proc == ARMCPU_ARM9) gl_VTX_end(); + return; + case cmd_3D_SWAP_BUFFERS // 0x04000540 : + case cmd_3D_VIEWPORT // 0x04000580 : + case cmd_3D_BOX_TEST // 0x040005C0 : + case cmd_3D_POS_TEST // 0x040005C4 : + case cmd_3D_VEC_TEST // 0x040005C8 : + if (proc == ARMCPU_ARM9) gl_print_cmd(adr); + return; +*/ + case REG_DISPA_DISPCNT : + if(proc == ARMCPU_ARM9) GPU_setVideoProp(state->MainScreen->gpu, val); + + //GPULOG("MAIN INIT 32B %08X\r\n", val); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0, val); + return; + + case REG_DISPB_DISPCNT : + if (proc == ARMCPU_ARM9) GPU_setVideoProp(state->SubScreen->gpu, val); + //GPULOG("SUB INIT 32B %08X\r\n", val); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x1000, val); + return; + case REG_VRAMCNTA: + case REG_VRAMCNTE: + MMU_write8(state,proc,adr,val & 0xFF) ; + MMU_write8(state,proc,adr+1,val >> 8) ; + MMU_write8(state,proc,adr+2,val >> 16) ; + MMU_write8(state,proc,adr+3,val >> 24) ; + return ; + case REG_VRAMCNTI: + MMU_write8(state,proc,adr,val & 0xFF) ; + return ; + + case REG_IME : { + u32 old_val = state->MMU->reg_IME[proc]; + u32 new_val = val & 1; + state->MMU->reg_IME[proc] = new_val; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x208, val); + if ( new_val && old_val != new_val) { + /* raise an interrupt request to the CPU if needed */ + if ( state->MMU->reg_IE[proc] & state->MMU->reg_IF[proc]) { + state->NDS_ARM7->wIRQ = TRUE; + state->NDS_ARM7->waitIRQ = FALSE; + } + } + return; + } + + case REG_IE : + state->MMU->reg_IE[proc] = val; + if ( state->MMU->reg_IME[proc]) { + /* raise an interrupt request to the CPU if needed */ + if ( state->MMU->reg_IE[proc] & state->MMU->reg_IF[proc]) { + state->NDS_ARM7->wIRQ = TRUE; + state->NDS_ARM7->waitIRQ = FALSE; + } + } + return; + + case REG_IF : + state->MMU->reg_IF[proc] &= (~val); + return; + case REG_TM0CNTL : + case REG_TM1CNTL : + case REG_TM2CNTL : + case REG_TM3CNTL : + state->MMU->timerReload[proc][(adr>>2)&0x3] = (u16)val; + if(val&0x800000) + { + state->MMU->timer[proc][(adr>>2)&0x3] = state->MMU->timerReload[proc][(adr>>2)&0x3]; + } + state->MMU->timerON[proc][(adr>>2)&0x3] = val & 0x800000; + switch((val>>16)&7) + { + case 0 : + state->MMU->timerMODE[proc][(adr>>2)&0x3] = 0+1;//proc; + break; + case 1 : + state->MMU->timerMODE[proc][(adr>>2)&0x3] = 6+1;//proc; + break; + case 2 : + state->MMU->timerMODE[proc][(adr>>2)&0x3] = 8+1;//proc; + break; + case 3 : + state->MMU->timerMODE[proc][(adr>>2)&0x3] = 10+1;//proc; + break; + default : + state->MMU->timerMODE[proc][(adr>>2)&0x3] = 0xFFFF; + break; + } + if(!(val & 0x800000)) + { + state->MMU->timerRUN[proc][(adr>>2)&0x3] = FALSE; + } + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], adr & 0xFFF, val); + return; + case REG_DIVDENOM : + { + u16 cnt; + s64 num = 0; + s64 den = 1; + s64 res; + s64 mod; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x298, val); + cnt = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x280); + switch(cnt&3) + { + case 0: + { + num = (s64) (s32) T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0x290); + den = (s64) (s32) T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0x298); + } + break; + case 1: + { + num = (s64) T1ReadQuad(state->MMU->MMU_MEM[proc][0x40], 0x290); + den = (s64) (s32) T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0x298); + } + break; + case 2: + { + return; + } + break; + default: + break; + } + if(den==0) + { + res = 0; + mod = 0; + cnt |= 0x4000; + cnt &= 0x7FFF; + } + else + { + res = num / den; + mod = num % den; + cnt &= 0x3FFF; + } + DIVLOG("BOUT1 %08X%08X / %08X%08X = %08X%08X\r\n", (u32)(num>>32), (u32)num, + (u32)(den>>32), (u32)den, + (u32)(res>>32), (u32)res); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2A0, (u32) res); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2A4, (u32) (res >> 32)); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2A8, (u32) mod); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2AC, (u32) (mod >> 32)); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x280, cnt); + } + return; + case REG_DIVDENOM+4 : + { + u16 cnt; + s64 num = 0; + s64 den = 1; + s64 res; + s64 mod; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x29C, val); + cnt = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x280); + switch(cnt&3) + { + case 0: + { + return; + } + break; + case 1: + { + return; + } + break; + case 2: + { + num = (s64) T1ReadQuad(state->MMU->MMU_MEM[proc][0x40], 0x290); + den = (s64) T1ReadQuad(state->MMU->MMU_MEM[proc][0x40], 0x298); + } + break; + default: + break; + } + if(den==0) + { + res = 0; + mod = 0; + cnt |= 0x4000; + cnt &= 0x7FFF; + } + else + { + res = num / den; + mod = num % den; + cnt &= 0x3FFF; + } + DIVLOG("BOUT2 %08X%08X / %08X%08X = %08X%08X\r\n", (u32)(num>>32), (u32)num, + (u32)(den>>32), (u32)den, + (u32)(res>>32), (u32)res); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2A0, (u32) res); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2A4, (u32) (res >> 32)); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2A8, (u32) mod); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2AC, (u32) (mod >> 32)); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x280, cnt); + } + return; + case REG_SQRTPARAM : + { + u16 cnt; + u64 v = 1; + //execute = FALSE; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2B8, val); + cnt = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x2B0); + switch(cnt&1) + { + case 0: + v = (u64) T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0x2B8); + break; + case 1: + return; + } + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2B4, (u32) sqrt((s64)v)); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2B0, cnt & 0x7FFF); + SQRTLOG("BOUT1 sqrt(%08X%08X) = %08X\r\n", (u32)(v>>32), (u32)v, + T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0x2B4)); + } + return; + case REG_SQRTPARAM+4 : + { + u16 cnt; + u64 v = 1; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2BC, val); + cnt = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x2B0); + switch(cnt&1) + { + case 0: + return; + //break; + case 1: + v = T1ReadQuad(state->MMU->MMU_MEM[proc][0x40], 0x2B8); + break; + } + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2B4, (u32) sqrt((s64)v)); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x2B0, cnt & 0x7FFF); + SQRTLOG("BOUT2 sqrt(%08X%08X) = %08X\r\n", (u32)(v>>32), (u32)v, + T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0x2B4)); + } + return; + case REG_IPCSYNC : + { + //execute=FALSE; + u32 remote = (proc+1)&1; + u32 IPCSYNC_remote = T1ReadLong(state->MMU->MMU_MEM[remote][0x40], 0x180); + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF)); + T1WriteLong(state->MMU->MMU_MEM[remote][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF)); + state->MMU->reg_IF[remote] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU->reg_IME[remote] << 16);// & (MMU->reg_IE[remote] & (1<<16));// + } + return; + case REG_IPCFIFOCNT : + { + u32 cnt_l = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x184) ; + u32 cnt_r = T1ReadWord(state->MMU->MMU_MEM[(proc+1) & 1][0x40], 0x184) ; + if ((val & 0x8000) && !(cnt_l & 0x8000)) + { + /* this is the first init, the other side didnt init yet */ + /* so do a complete init */ + FIFOInit(state->MMU->fifos + (IPCFIFO+proc)); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x184,0x8101) ; + /* and then handle it as usual */ + } + if(val & 0x4008) + { + FIFOInit(state->MMU->fifos + (IPCFIFO+((proc+1)&1))); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1); + T1WriteWord(state->MMU->MMU_MEM[proc^1][0x40], 0x184, (cnt_r & 0xC507) | 0x100); + state->MMU->reg_IF[proc] |= ((val & 4)<<15);// & (MMU->reg_IME[proc]<<17);// & (MMU->reg_IE[proc]&0x20000);// + return; + } + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x184, val & 0xBFF4); + //execute = FALSE; + return; + } + case REG_IPCFIFOSEND : + { + u16 IPCFIFO_CNT = T1ReadWord(state->MMU->MMU_MEM[proc][0x40], 0x184); + if(IPCFIFO_CNT&0x8000) + { + //if(val==43) execute = FALSE; + u32 remote = (proc+1)&1; + u32 fifonum = IPCFIFO+remote; + u16 IPCFIFO_CNT_remote; + FIFOAdd(state->MMU->fifos + fifonum, val); + IPCFIFO_CNT = (IPCFIFO_CNT & 0xFFFC) | (state->MMU->fifos[fifonum].full<<1); + IPCFIFO_CNT_remote = T1ReadWord(state->MMU->MMU_MEM[remote][0x40], 0x184); + IPCFIFO_CNT_remote = (IPCFIFO_CNT_remote & 0xFCFF) | (state->MMU->fifos[fifonum].full<<10); + T1WriteWord(state->MMU->MMU_MEM[proc][0x40], 0x184, IPCFIFO_CNT); + T1WriteWord(state->MMU->MMU_MEM[remote][0x40], 0x184, IPCFIFO_CNT_remote); + state->MMU->reg_IF[remote] |= ((IPCFIFO_CNT_remote & (1<<10))<<8);// & (MMU->reg_IME[remote] << 18);// & (MMU->reg_IE[remote] & 0x40000);// + //execute = FALSE; + } + } + return; + case REG_DMA0CNTL : + //LOG("32 bit dma0 %04X\r\n", val); + state->DMASrc[proc][0] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xB0); + state->DMADst[proc][0] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xB4); + state->MMU->DMAStartTime[proc][0] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7); + state->MMU->DMACrt[proc][0] = val; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0xB8, val); + if( state->MMU->DMAStartTime[proc][0] == 0 || + state->MMU->DMAStartTime[proc][0] == 7) // Start Immediately + MMU_doDMA(state, proc, 0); + #ifdef LOG_DMA2 + else + { + LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 0, state->DMASrc[proc][0], state->DMADst[proc][0], 0, ((state->MMU->DMACrt[proc][0]>>27)&7)); + } + #endif + //execute = FALSE; + return; + case REG_DMA1CNTL: + //LOG("32 bit dma1 %04X\r\n", val); + state->DMASrc[proc][1] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xBC); + state->DMADst[proc][1] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xC0); + state->MMU->DMAStartTime[proc][1] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7); + state->MMU->DMACrt[proc][1] = val; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0xC4, val); + if(state->MMU->DMAStartTime[proc][1] == 0 || + state->MMU->DMAStartTime[proc][1] == 7) // Start Immediately + MMU_doDMA(state, proc, 1); + #ifdef LOG_DMA2 + else + { + LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 1, state->DMASrc[proc][1], state->DMADst[proc][1], 0, ((state->MMU->DMACrt[proc][1]>>27)&7)); + } + #endif + return; + case REG_DMA2CNTL : + //LOG("32 bit dma2 %04X\r\n", val); + state->DMASrc[proc][2] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xC8); + state->DMADst[proc][2] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xCC); + state->MMU->DMAStartTime[proc][2] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7); + state->MMU->DMACrt[proc][2] = val; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0xD0, val); + if(state->MMU->DMAStartTime[proc][2] == 0 || + state->MMU->DMAStartTime[proc][2] == 7) // Start Immediately + MMU_doDMA(state, proc, 2); + #ifdef LOG_DMA2 + else + { + LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 2, state->DMASrc[proc][2], state->DMADst[proc][2], 0, ((state->MMU->DMACrt[proc][2]>>27)&7)); + } + #endif + return; + case 0x040000DC : + //LOG("32 bit dma3 %04X\r\n", val); + state->DMASrc[proc][3] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xD4); + state->DMADst[proc][3] = T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xD8); + state->MMU->DMAStartTime[proc][3] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7); + state->MMU->DMACrt[proc][3] = val; + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0xDC, val); + if( state->MMU->DMAStartTime[proc][3] == 0 || + state->MMU->DMAStartTime[proc][3] == 7) // Start Immediately + MMU_doDMA(state, proc, 3); + #ifdef LOG_DMA2 + else + { + LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 3, state->DMASrc[proc][3], state->DMADst[proc][3], 0, ((state->MMU->DMACrt[proc][3]>>27)&7)); + } + #endif + return; + case REG_GCROMCTRL : + { + int i; + + if(MEM_8(state->MMU->MMU_MEM[proc], REG_GCCMDOUT) == 0xB7) + { + state->MMU->dscard[proc].adress = (MEM_8(state->MMU->MMU_MEM[proc], REG_GCCMDOUT+1) << 24) | (MEM_8(state->MMU->MMU_MEM[proc], REG_GCCMDOUT+2) << 16) | (MEM_8(state->MMU->MMU_MEM[proc], REG_GCCMDOUT+3) << 8) | (MEM_8(state->MMU->MMU_MEM[proc], REG_GCCMDOUT+4)); + state->MMU->dscard[proc].transfer_count = 0x80;// * ((val>>24)&7)); + } + else if (MEM_8(state->MMU->MMU_MEM[proc], REG_GCCMDOUT) == 0xB8) + { + // Get ROM chip ID + val |= 0x800000; // Data-Word Status + T1WriteLong(state->MMU->MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); + state->MMU->dscard[proc].adress = 0; + } + else + { + LOG("CARD command: %02X\n", MEM_8(state->MMU->MMU_MEM[proc], REG_GCCMDOUT)); + } + + //CARDLOG("%08X : %08X %08X\r\n", adr, val, adresse[proc]); + val |= 0x00800000; + + if(state->MMU->dscard[proc].adress == 0) + { + val &= ~0x80000000; + T1WriteLong(state->MMU->MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); + return; + } + T1WriteLong(state->MMU->MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); + + /* launch DMA if start flag was set to "DS Cart" */ + if(proc == ARMCPU_ARM7) i = 2; + else i = 5; + + if(proc == ARMCPU_ARM9 && state->MMU->DMAStartTime[proc][0] == i) /* dma0/1 on arm7 can't start on ds cart event */ + { + MMU_doDMA(state, proc, 0); + return; + } + else if(proc == ARMCPU_ARM9 && state->MMU->DMAStartTime[proc][1] == i) + { + MMU_doDMA(state, proc, 1); + return; + } + else if(state->MMU->DMAStartTime[proc][2] == i) + { + MMU_doDMA(state, proc, 2); + return; + } + else if(state->MMU->DMAStartTime[proc][3] == i) + { + MMU_doDMA(state, proc, 3); + return; + } + return; + + } + return; + case REG_DISPA_DISPCAPCNT : + if(proc == ARMCPU_ARM9) + { + GPU_set_DISPCAPCNT(state->MainScreen->gpu,val); + T1WriteLong(state->ARM9Mem->ARM9_REG, 0x64, val); + } + return; + + case REG_DISPA_BG0CNT : + if (proc == ARMCPU_ARM9) + { + GPU_setBGProp(state->MainScreen->gpu, 0, (val&0xFFFF)); + GPU_setBGProp(state->MainScreen->gpu, 1, (val>>16)); + } + //if((val>>16)==0x400) execute = FALSE; + T1WriteLong(state->ARM9Mem->ARM9_REG, 8, val); + return; + case REG_DISPA_BG2CNT : + if (proc == ARMCPU_ARM9) + { + GPU_setBGProp(state->MainScreen->gpu, 2, (val&0xFFFF)); + GPU_setBGProp(state->MainScreen->gpu, 3, (val>>16)); + } + T1WriteLong(state->ARM9Mem->ARM9_REG, 0xC, val); + return; + case REG_DISPB_BG0CNT : + if (proc == ARMCPU_ARM9) + { + GPU_setBGProp(state->SubScreen->gpu, 0, (val&0xFFFF)); + GPU_setBGProp(state->SubScreen->gpu, 1, (val>>16)); + } + T1WriteLong(state->ARM9Mem->ARM9_REG, 0x1008, val); + return; + case REG_DISPB_BG2CNT : + if (proc == ARMCPU_ARM9) + { + GPU_setBGProp(state->SubScreen->gpu, 2, (val&0xFFFF)); + GPU_setBGProp(state->SubScreen->gpu, 3, (val>>16)); + } + T1WriteLong(state->ARM9Mem->ARM9_REG, 0x100C, val); + return; + case REG_DISPA_DISPMMEMFIFO: + { + // NOTE: right now, the capture unit is not taken into account, + // I don't know is it should be handled here or + + FIFOAdd(state->MMU->fifos + MAIN_MEMORY_DISP_FIFO, val); + break; + } + //case 0x21FDFF0 : if(val==0) execute = FALSE; + //case 0x21FDFB0 : if(val==0) execute = FALSE; + default : + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], adr & state->MMU->MMU_MASK[proc][(adr>>20)&0xFF], val); + return; + } + } + T1WriteLong(state->MMU->MMU_MEM[proc][(adr>>20)&0xFF], adr&state->MMU->MMU_MASK[proc][(adr>>20)&0xFF], val); +} + + +void FASTCALL MMU_doDMA(NDS_state *state, u32 proc, u32 num) +{ + u32 src = state->DMASrc[proc][num]; + u32 dst = state->DMADst[proc][num]; + u32 taille; + + if(src==dst) + { + T1WriteLong(state->MMU->MMU_MEM[proc][0x40], 0xB8 + (0xC*num), T1ReadLong(state->MMU->MMU_MEM[proc][0x40], 0xB8 + (0xC*num)) & 0x7FFFFFFF); + return; + } + + if((!(state->MMU->DMACrt[proc][num]&(1<<31)))&&(!(state->MMU->DMACrt[proc][num]&(1<<25)))) + { /* not enabled and not to be repeated */ + state->MMU->DMAStartTime[proc][num] = 0; + state->MMU->DMACycle[proc][num] = 0; + //MMU->DMAing[proc][num] = FALSE; + return; + } + + + /* word count */ + taille = (state->MMU->DMACrt[proc][num]&0xFFFF); + + // If we are in "Main memory display" mode just copy an entire + // screen (256x192 pixels). + // Reference: http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode + // (under DISP_MMEM_FIFO) + if ((state->MMU->DMAStartTime[proc][num]==4) && // Must be in main memory display mode + (taille==4) && // Word must be 4 + (((state->MMU->DMACrt[proc][num]>>26)&1) == 1)) // Transfer mode must be 32bit wide + taille = 256*192/2; + + if(state->MMU->DMAStartTime[proc][num] == 5) + taille *= 0x80; + + state->MMU->DMACycle[proc][num] = taille + state->nds->cycles; + state->MMU->DMAing[proc][num] = TRUE; + + DMALOG("proc %d, dma %d src %08X dst %08X start %d taille %d repeat %s %08X\r\n", + proc, num, src, dst, state->MMU->DMAStartTime[proc][num], taille, + (state->MMU->DMACrt[proc][num]&(1<<25))?"on":"off",state->MMU->DMACrt[proc][num]); + + if(!(state->MMU->DMACrt[proc][num]&(1<<25))) + state->MMU->DMAStartTime[proc][num] = 0; + + // transfer + { + u32 i=0; + // 32 bit or 16 bit transfer ? + int sz = ((state->MMU->DMACrt[proc][num]>>26)&1)? 4 : 2; + int dstinc,srcinc; + int u=(state->MMU->DMACrt[proc][num]>>21); + switch(u & 0x3) { + case 0 : dstinc = sz; break; + case 1 : dstinc = -sz; break; + case 2 : dstinc = 0; break; + case 3 : dstinc = sz; break; //reload + } + switch((u >> 2)&0x3) { + case 0 : srcinc = sz; break; + case 1 : srcinc = -sz; break; + case 2 : srcinc = 0; break; + case 3 : // reserved + return; + } + if ((state->MMU->DMACrt[proc][num]>>26)&1) + for(; i < taille; ++i) + { + MMU_write32(state, proc, dst, MMU_read32(state, proc, src)); + dst += dstinc; + src += srcinc; + } + else + for(; i < taille; ++i) + { + MMU_write16(state, proc, dst, MMU_read16(state, proc, src)); + dst += dstinc; + src += srcinc; + } + } +} + +#ifdef MMU_ENABLE_ACL + +INLINE void check_access(NDS_state *state, u32 adr, u32 access) { + /* every other mode: sys */ + access |= 1; + if ((state->NDS_ARM9->CPSR.val & 0x1F) == 0x10) { + /* is user mode access */ + access ^= 1 ; + } + if (armcp15_isAccessAllowed((armcp15_t *)state->NDS_ARM9->coproc[15],adr,access)==FALSE) { + state->execute = FALSE ; + } +} +INLINE void check_access_write(NDS_State *state, u32 adr) { + u32 access = CP15_ACCESS_WRITE; + check_access(state, adr, access) +} + +u8 FASTCALL MMU_read8_acl(NDS_state *state, u32 proc, u32 adr, u32 access) +{ + /* on arm9 we need to check the MPU regions */ + if (proc == ARMCPU_ARM9) + check_access(state, adr, access); + return MMU_read8(state,proc,adr); +} +u16 FASTCALL MMU_read16_acl(NDS_state *state, u32 proc, u32 adr, u32 access) +{ + /* on arm9 we need to check the MPU regions */ + if (proc == ARMCPU_ARM9) + check_access(state, adr, access); + return MMU_read16(state,proc,adr); +} +u32 FASTCALL MMU_read32_acl(NDS_state *state, u32 proc, u32 adr, u32 access) +{ + /* on arm9 we need to check the MPU regions */ + if (proc == ARMCPU_ARM9) + check_access(state, adr, access); + return MMU_read32(state,proc,adr); +} + +void FASTCALL MMU_write8_acl(NDS_state *state, u32 proc, u32 adr, u8 val) +{ + /* check MPU region on ARM9 */ + if (proc == ARMCPU_ARM9) + check_access_write(state,adr); + MMU_write8(state,proc,adr,val); +} +void FASTCALL MMU_write16_acl(NDS_state *state, u32 proc, u32 adr, u16 val) +{ + /* check MPU region on ARM9 */ + if (proc == ARMCPU_ARM9) + check_access_write(state,adr); + MMU_write16(state,proc,adr,val) ; +} +void FASTCALL MMU_write32_acl(NDS_state *state, u32 proc, u32 adr, u32 val) +{ + /* check MPU region on ARM9 */ + if (proc == ARMCPU_ARM9) + check_access_write(state,adr); + MMU_write32(state,proc,adr,val) ; +} +#endif + + + +#ifdef PROFILE_MEMORY_ACCESS + +#define PROFILE_PREFETCH 0 +#define PROFILE_READ 1 +#define PROFILE_WRITE 2 + +struct mem_access_profile { + u64 num_accesses; + u32 address_mask; + u32 masked_value; +}; + +#define PROFILE_NUM_MEM_ACCESS_PROFILES 4 + +static u64 profile_num_accesses[2][3]; +static u64 profile_unknown_addresses[2][3]; +static struct mem_access_profile +profile_memory_accesses[2][3][PROFILE_NUM_MEM_ACCESS_PROFILES]; + +static void +setup_profiling( void) { + int i; + + for ( i = 0; i < 2; i++) { + int access_type; + + for ( access_type = 0; access_type < 3; access_type++) { + profile_num_accesses[i][access_type] = 0; + profile_unknown_addresses[i][access_type] = 0; + + /* + * Setup the access testing structures + */ + profile_memory_accesses[i][access_type][0].address_mask = 0x0e000000; + profile_memory_accesses[i][access_type][0].masked_value = 0x00000000; + profile_memory_accesses[i][access_type][0].num_accesses = 0; + + /* main memory */ + profile_memory_accesses[i][access_type][1].address_mask = 0x0f000000; + profile_memory_accesses[i][access_type][1].masked_value = 0x02000000; + profile_memory_accesses[i][access_type][1].num_accesses = 0; + + /* shared memory */ + profile_memory_accesses[i][access_type][2].address_mask = 0x0f800000; + profile_memory_accesses[i][access_type][2].masked_value = 0x03000000; + profile_memory_accesses[i][access_type][2].num_accesses = 0; + + /* arm7 memory */ + profile_memory_accesses[i][access_type][3].address_mask = 0x0f800000; + profile_memory_accesses[i][access_type][3].masked_value = 0x03800000; + profile_memory_accesses[i][access_type][3].num_accesses = 0; + } + } +} + +static void +profile_memory_access( int arm9, u32 adr, int access_type) { + static int first = 1; + int mem_profile; + int address_found = 0; + + if ( first) { + setup_profiling(); + first = 0; + } + + profile_num_accesses[arm9][access_type] += 1; + + for ( mem_profile = 0; + mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES && + !address_found; + mem_profile++) { + if ( (adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask) == + profile_memory_accesses[arm9][access_type][mem_profile].masked_value) { + /*printf( "adr %08x mask %08x res %08x expected %08x\n", + adr, + profile_memory_accesses[arm9][access_type][mem_profile].address_mask, + adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask, + profile_memory_accesses[arm9][access_type][mem_profile].masked_value);*/ + address_found = 1; + profile_memory_accesses[arm9][access_type][mem_profile].num_accesses += 1; + } + } + + if ( !address_found) { + profile_unknown_addresses[arm9][access_type] += 1; + } +} + + +static const char *access_type_strings[] = { + "prefetch", + "read ", + "write " +}; + +void +print_memory_profiling( void) { + int arm; + + printf("------ Memory access profile ------\n"); + + for ( arm = 0; arm < 2; arm++) { + int access_type; + + for ( access_type = 0; access_type < 3; access_type++) { + int mem_profile; + printf("ARM%c: num of %s %lld\n", + arm ? '9' : '7', + access_type_strings[access_type], + profile_num_accesses[arm][access_type]); + + for ( mem_profile = 0; + mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES; + mem_profile++) { + printf( "address %08x: %lld\n", + profile_memory_accesses[arm][access_type][mem_profile].masked_value, + profile_memory_accesses[arm][access_type][mem_profile].num_accesses); + } + + printf( "unknown addresses %lld\n", + profile_unknown_addresses[arm][access_type]); + + printf( "\n"); + } + } + + printf("------ End of Memory access profile ------\n\n"); +} +#else +void +print_memory_profiling( void) { +} +#endif /* End of PROFILE_MEMORY_ACCESS area */ + +static u16 FASTCALL +arm9_prefetch16( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 1, adr, PROFILE_PREFETCH); +#endif + +#ifdef EARLY_MEMORY_ACCESS + if((adr & ~0x3FFF) == state->MMU->DTCMRegion) + { + /* Returns data from DTCM (ARM9 only) */ + return T1ReadWord(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF); + } + /* access to main memory */ + if ( (adr & 0x0f000000) == 0x02000000) { + return T1ReadWord( state->MMU->MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF], + adr & state->MMU->MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]); + } +#endif + + return MMU_read16( state, ARMCPU_ARM9, adr); +} +static u32 FASTCALL +arm9_prefetch32( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 1, adr, PROFILE_PREFETCH); +#endif + +#ifdef EARLY_MEMORY_ACCESS + if((adr & ~0x3FFF) == state->MMU->DTCMRegion) + { + /* Returns data from DTCM (ARM9 only) */ + return T1ReadLong(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF); + } + /* access to main memory */ + if ( (adr & 0x0f000000) == 0x02000000) { + return T1ReadLong( state->MMU->MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF], + adr & state->MMU->MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]); + } +#endif + + return MMU_read32( state, ARMCPU_ARM9, adr); +} + +static u8 FASTCALL +arm9_read8( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 1, adr, PROFILE_READ); +#endif + +#ifdef EARLY_MEMORY_ACCESS + if( (adr&(~0x3FFF)) == state->MMU->DTCMRegion) + { + return state->ARM9Mem->ARM9_DTCM[adr&0x3FFF]; + } + /* access to main memory */ + if ( (adr & 0x0f000000) == 0x02000000) { + return state->MMU->MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF] + [adr & state->MMU->MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]]; + } +#endif + + return MMU_read8( state, ARMCPU_ARM9, adr); +} +static u16 FASTCALL +arm9_read16( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 1, adr, PROFILE_READ); +#endif + +#ifdef EARLY_MEMORY_ACCESS + if((adr & ~0x3FFF) == state->MMU->DTCMRegion) + { + /* Returns data from DTCM (ARM9 only) */ + return T1ReadWord(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF); + } + + /* access to main memory */ + if ( (adr & 0x0f000000) == 0x02000000) { + return T1ReadWord( state->MMU->MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF], + adr & state->MMU->MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]); + } +#endif + + return MMU_read16( state, ARMCPU_ARM9, adr); +} +static u32 FASTCALL +arm9_read32( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 1, adr, PROFILE_READ); +#endif + +#ifdef EARLY_MEMORY_ACCESS + if((adr & ~0x3FFF) == state->MMU->DTCMRegion) + { + /* Returns data from DTCM (ARM9 only) */ + return T1ReadLong(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF); + } + /* access to main memory */ + if ( (adr & 0x0f000000) == 0x02000000) { + return T1ReadLong( state->MMU->MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF], + adr & state->MMU->MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]); + } +#endif + + return MMU_read32( state, ARMCPU_ARM9, adr); +} + + +static void FASTCALL +arm9_write8(NDS_state *state, void *data, u32 adr, u8 val) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 1, adr, PROFILE_WRITE); +#endif + +#ifdef EARLY_MEMORY_ACCESS + if( (adr & ~0x3FFF) == state->MMU->DTCMRegion) + { + /* Writes data in DTCM (ARM9 only) */ + state->ARM9Mem->ARM9_DTCM[adr&0x3FFF] = val; + return ; + } + /* main memory */ + if ( (adr & 0x0f000000) == 0x02000000) { + state->MMU->MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF] + [adr&state->MMU->MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]] = val; + return; + } +#endif + + MMU_write8( state, ARMCPU_ARM9, adr, val); +} +static void FASTCALL +arm9_write16(NDS_state *state, void *data, u32 adr, u16 val) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 1, adr, PROFILE_WRITE); +#endif + +#ifdef EARLY_MEMORY_ACCESS + if((adr & ~0x3FFF) == state->MMU->DTCMRegion) + { + /* Writes in DTCM (ARM9 only) */ + T1WriteWord(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF, val); + return; + } + /* main memory */ + if ( (adr & 0x0f000000) == 0x02000000) { + T1WriteWord( state->MMU->MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF], + adr&state->MMU->MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF], val); + return; + } +#endif + + MMU_write16( state, ARMCPU_ARM9, adr, val); +} +static void FASTCALL +arm9_write32(NDS_state *state, void *data, u32 adr, u32 val) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 1, adr, PROFILE_WRITE); +#endif + +#ifdef EARLY_MEMORY_ACCESS + if((adr & ~0x3FFF) == state->MMU->DTCMRegion) + { + /* Writes in DTCM (ARM9 only) */ + T1WriteLong(state->ARM9Mem->ARM9_DTCM, adr & 0x3FFF, val); + return; + } + /* main memory */ + if ( (adr & 0x0f000000) == 0x02000000) { + T1WriteLong( state->MMU->MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF], + adr&state->MMU->MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF], val); + return; + } +#endif + + MMU_write32( state, ARMCPU_ARM9, adr, val); +} + + + + +static u16 FASTCALL +arm7_prefetch16( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 0, adr, PROFILE_PREFETCH); +#endif + +#ifdef EARLY_MEMORY_ACCESS + /* ARM7 private memory */ + if ( (adr & 0x0f800000) == 0x03800000) { + T1ReadWord(state->MMU->MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF], + adr & state->MMU->MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]); + } +#endif + + return MMU_read16( state, ARMCPU_ARM7, adr); +} +static u32 FASTCALL +arm7_prefetch32( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 0, adr, PROFILE_PREFETCH); +#endif + +#ifdef EARLY_MEMORY_ACCESS + /* ARM7 private memory */ + if ( (adr & 0x0f800000) == 0x03800000) { + T1ReadLong(state->MMU->MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF], + adr & state->MMU->MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]); + } +#endif + + return MMU_read32( state, ARMCPU_ARM7, adr); +} + +static u8 FASTCALL +arm7_read8( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 0, adr, PROFILE_READ); +#endif + + return MMU_read8( state, ARMCPU_ARM7, adr); +} +static u16 FASTCALL +arm7_read16( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 0, adr, PROFILE_READ); +#endif + + return MMU_read16( state, ARMCPU_ARM7, adr); +} +static u32 FASTCALL +arm7_read32( NDS_state *state, void *data, u32 adr) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 0, adr, PROFILE_READ); +#endif + + return MMU_read32( state, ARMCPU_ARM7, adr); +} + + +static void FASTCALL +arm7_write8(NDS_state *state, void *data, u32 adr, u8 val) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 0, adr, PROFILE_WRITE); +#endif + + MMU_write8( state, ARMCPU_ARM7, adr, val); +} +static void FASTCALL +arm7_write16(NDS_state *state, void *data, u32 adr, u16 val) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 0, adr, PROFILE_WRITE); +#endif + + MMU_write16( state, ARMCPU_ARM7, adr, val); +} +static void FASTCALL +arm7_write32(NDS_state *state, void *data, u32 adr, u32 val) { +#ifdef PROFILE_MEMORY_ACCESS + profile_memory_access( 0, adr, PROFILE_WRITE); +#endif + + MMU_write32( state, ARMCPU_ARM7, adr, val); +} + + +#ifdef GDB_STUB +/* + * the base memory interfaces + */ +struct armcpu_memory_iface arm9_base_memory_iface = { +#ifdef __GNUC__ + .prefetch32 = arm9_prefetch32, + .prefetch16 = arm9_prefetch16, + + .read8 = arm9_read8, + .read16 = arm9_read16, + .read32 = arm9_read32, + + .write8 = arm9_write8, + .write16 = arm9_write16, + .write32 = arm9_write32 +#else + arm9_prefetch32, + arm9_prefetch16, + + arm9_read8, + arm9_read16, + arm9_read32, + + arm9_write8, + arm9_write16, + arm9_write32 +#endif +}; + +struct armcpu_memory_iface arm7_base_memory_iface = { +#ifdef __GNUC__ + .prefetch32 = arm7_prefetch32, + .prefetch16 = arm7_prefetch16, + + .read8 = arm7_read8, + .read16 = arm7_read16, + .read32 = arm7_read32, + + .write8 = arm7_write8, + .write16 = arm7_write16, + .write32 = arm7_write32 +#else + arm7_prefetch32, + arm7_prefetch16, + + arm7_read8, + arm7_read16, + arm7_read32, + + arm7_write8, + arm7_write16, + arm7_write32 +#endif +}; + +/* + * The direct memory interface for the ARM9. + * This avoids the ARM9 protection unit when accessing + * memory. + */ +struct armcpu_memory_iface arm9_direct_memory_iface = { +#ifdef __GNUC__ + /* the prefetch is not used */ + .prefetch32 = NULL, + .prefetch16 = NULL, + + .read8 = arm9_read8, + .read16 = arm9_read16, + .read32 = arm9_read32, + + .write8 = arm9_write8, + .write16 = arm9_write16, + .write32 = arm9_write32 +#else + NULL, + NULL, + + arm9_read8, + arm9_read16, + arm9_read32, + + arm9_write8, + arm9_write16, + arm9_write32 +#endif +}; +#endif diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/MMU.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/MMU.h new file mode 100755 index 000000000..68574c3fb --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/MMU.h @@ -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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/NDSSystem.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/NDSSystem.c new file mode 100755 index 000000000..f1c892539 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/NDSSystem.c @@ -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 +#include + +#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->ARM9Cyclends->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); + } +} + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/NDSSystem.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/NDSSystem.h new file mode 100755 index 000000000..79163b46f --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/NDSSystem.h @@ -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 + + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/SPU.cpp b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/SPU.cpp new file mode 100755 index 000000000..a120225f2 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/SPU.cpp @@ -0,0 +1,1074 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + Copyright (C) 2006 Theo Berkau + Copyright (C) 2008-2009 DeSmuME team + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include + +//#undef FORCEINLINE +//#define FORCEINLINE + +#define _SPU_CPP_ + +#define _USE_MATH_DEFINES +#include +#ifndef M_PI +#define M_PI 3.1415926535897932386 +#endif + +#define K_ADPCM_LOOPING_RECOVERY_INDEX 99999 + +#include "debug.h" +#include "MMU.h" +#include "SPU.h" +#include "mem.h" +#include "armcpu.h" +#include "NDSSystem.h" +#include "matrix.h" + +#include "state.h" + +//===================CONFIGURATION======================== +bool isChannelMuted(NDS_state *state, int num) { return state->dwChannelMute&(1<dwInterpolation; } +//========================================================= + +//#undef FORCEINLINE +//#define FORCEINLINE + +//const int shift = (FORMAT == 0 ? 2 : 1); +static const int format_shift[] = { 2, 1, 3, 0 }; + +static const s8 indextbl[8] = +{ + -1, -1, -1, -1, 2, 4, 6, 8 +}; + +static const u16 adpcmtbl[89] = +{ + 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010, + 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025, + 0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042, 0x0049, 0x0050, 0x0058, + 0x0061, 0x006B, 0x0076, 0x0082, 0x008F, 0x009D, 0x00AD, 0x00BE, 0x00D1, + 0x00E6, 0x00FD, 0x0117, 0x0133, 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE, + 0x0220, 0x0256, 0x0292, 0x02D4, 0x031C, 0x036C, 0x03C3, 0x0424, 0x048E, + 0x0502, 0x0583, 0x0610, 0x06AB, 0x0756, 0x0812, 0x08E0, 0x09C3, 0x0ABD, + 0x0BD0, 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE, 0x1706, 0x1954, + 0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B, 0x3BB9, + 0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF +}; + +static const s16 wavedutytbl[8][8] = { + { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF }, + { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF }, + { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF }, + { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF }, + { -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF }, + { -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF }, + { -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF }, + { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF } +}; + +static s32 precalcdifftbl[89][16]; +static u8 precalcindextbl[89][8]; + +static const double ARM7_CLOCK = 33513982; + +////////////////////////////////////////////////////////////////////////////// + +template +static FORCEINLINE T MinMax(T val, T min, T max) +{ + if (val < min) + return min; + else if (val > max) + return max; + + return val; +} + +////////////////////////////////////////////////////////////////////////////// + +extern "C" int SPU_ChangeSoundCore(NDS_state *state, int coreid, int buffersize) +{ + int i; + + delete state->SPU_user; state->SPU_user = 0; + + // Make sure the old core is freed + if (state->SNDCore) + state->SNDCore->DeInit(state); + + // So which core do we want? + if (coreid == SNDCORE_DEFAULT) + coreid = 0; // Assume we want the first one + + state->SPU_currentCoreNum = coreid; + + // Go through core list and find the id + for (i = 0; SNDCoreList[i] != NULL; i++) + { + if (SNDCoreList[i]->id == coreid) + { + // Set to current core + state->SNDCore = SNDCoreList[i]; + break; + } + } + + //If the user picked the dummy core, disable the user spu + if(state->SNDCore == &SNDDummy) + return 0; + + //If the core wasnt found in the list for some reason, disable the user spu + if (state->SNDCore == NULL) + return -1; + + // Since it failed, instead of it being fatal, disable the user spu + if (state->SNDCore->Init(state, buffersize * 2) == -1) + { + state->SNDCore = 0; + return -1; + } + + //enable the user spu + //well, not really + //SPU_user = new SPU_struct(buffersize); + + return 0; +} + +SoundInterface_struct *SPU_SoundCore(NDS_state *state) +{ + return state->SNDCore; +} + +extern "C" void SPU_Reset(NDS_state *state) +{ + int i; + + state->SPU_core->reset(); + if(state->SPU_user) state->SPU_user->reset(); + + if(state->SNDCore && state->SPU_user) { + state->SNDCore->DeInit(state); + state->SNDCore->Init(state, state->SPU_user->bufsize*2); + //todo - check success? + } + + // Reset Registers + for (i = 0x400; i < 0x51D; i++) + T1WriteByte(state->MMU->ARM7_REG, i, 0); + + state->samples = 0; +} + + +////////////////////////////////////////////////////////////////////////////// + +//static double cos_lut[256]; + + + +extern "C" int SPU_Init(NDS_state *state, int coreid, int buffersize) +{ + int i, j; + + //__asm int 3; + + //for(int i=0;i<256;i++) + // cos_lut[i] = cos(i/256.0*M_PI); + + state->SPU_core = new SPU_struct(state, 44100); //pick a really big number just to make sure the plugin doesnt request more + SPU_Reset(state); + + for(i = 0; i < 16; i++) + { + for(j = 0; j < 89; j++) + { + precalcdifftbl[j][i] = (((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8); + if(i & 0x8) precalcdifftbl[j][i] = -precalcdifftbl[j][i]; + } + } + + for(i = 0; i < 8; i++) + { + for(j = 0; j < 89; j++) + { + precalcindextbl[j][i] = MinMax((j + indextbl[i]), 0, 88); + } + } + + //return SPU_ChangeSoundCore(coreid, buffersize); + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +void SPU_Pause(NDS_state *state, int pause) +{ + if (state->SNDCore == NULL) return; + + if(pause) + state->SNDCore->MuteAudio(state); + else + state->SNDCore->UnMuteAudio(state); +} + +////////////////////////////////////////////////////////////////////////////// + +void SPU_SetVolume(NDS_state *state, int volume) +{ + if (state->SNDCore) + state->SNDCore->SetVolume(state, volume); +} + +////////////////////////////////////////////////////////////////////////////// + + + +void SPU_struct::reset() +{ + memset(sndbuf,0,bufsize*2*4); + memset(outbuf,0,bufsize*2*2); + + memset((void *)channels, 0, sizeof(channel_struct) * 16); + + for(int i = 0; i < 16; i++) + { + channels[i].num = i; + } +} + +SPU_struct::SPU_struct(struct NDS_state *pstate, int buffersize) + : state(pstate) + , bufpos(0) + , buflength(0) + , sndbuf(0) + , outbuf(0) + , bufsize(buffersize) +{ + sndbuf = new s32[buffersize*2]; + outbuf = new s16[buffersize*2]; + reset(); +} + +SPU_struct::~SPU_struct() +{ + if(sndbuf) delete[] sndbuf; + if(outbuf) delete[] outbuf; +} + +extern "C" void SPU_DeInit(NDS_state *state) +{ + if(state->SNDCore) + state->SNDCore->DeInit(state); + state->SNDCore = 0; + + delete state->SPU_core; state->SPU_core=0; + delete state->SPU_user; state->SPU_user=0; +} + +////////////////////////////////////////////////////////////////////////////// + +void SPU_struct::ShutUp() +{ + for(int i=0;i<16;i++) + channels[i].status = CHANSTAT_STOPPED; +} + +static FORCEINLINE void adjust_channel_timer(channel_struct *chan) +{ + chan->sampinc = (((double)ARM7_CLOCK) / (44100 * 2)) / (double)(0x10000 - chan->timer); +} + +void SPU_struct::KeyOn(int channel) +{ + channel_struct &thischan = channels[channel]; + + adjust_channel_timer(&thischan); + + // LOG("Channel %d key on: vol = %d, datashift = %d, hold = %d, pan = %d, waveduty = %d, repeat = %d, format = %d, source address = %07X, timer = %04X, loop start = %04X, length = %06X, cpu->state->MMUARM7_REG[0x501] = %02X\n", channel, chan->vol, chan->datashift, chan->hold, chan->pan, chan->waveduty, chan->repeat, chan->format, chan->addr, chan->timer, chan->loopstart, chan->length, T1ReadByte(MMU->ARM7_REG, 0x501)); + switch(thischan.format) + { + case 0: // 8-bit + thischan.buf8 = (s8*)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; + // thischan.loopstart = thischan.loopstart << 2; + // thischan.length = (thischan.length << 2) + thischan.loopstart; + thischan.sampcnt = 0; + break; + case 1: // 16-bit + thischan.buf16 = (s16 *)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; + // thischan.loopstart = thischan.loopstart << 1; + // thischan.length = (thischan.length << 1) + thischan.loopstart; + thischan.sampcnt = 0; + break; + case 2: // ADPCM + { + thischan.buf8 = (s8*)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; + thischan.pcm16b = (s16)((thischan.buf8[1] << 8) | thischan.buf8[0]); + thischan.pcm16b_last = thischan.pcm16b; + thischan.index = thischan.buf8[2] & 0x7F; + thischan.lastsampcnt = 7; + thischan.sampcnt = 8; + thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX; + // thischan.loopstart = thischan.loopstart << 3; + // thischan.length = (thischan.length << 3) + thischan.loopstart; + break; + } + case 3: // PSG + { + thischan.x = 0x7FFF; + break; + } + default: break; + } + + if(thischan.format != 3) + { + if(thischan.double_totlength_shifted == 0) + { + printf("INFO: Stopping channel %d due to zero length\n",channel); + thischan.status = CHANSTAT_STOPPED; + } + } + + thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]); +} + +////////////////////////////////////////////////////////////////////////////// + +void SPU_struct::WriteByte(u32 addr, u8 val) +{ + channel_struct &thischan=channels[(addr >> 4) & 0xF]; + switch(addr & 0xF) { + case 0x0: + thischan.vol = val & 0x7F; + break; + case 0x1: { + thischan.datashift = val & 0x3; + if (thischan.datashift == 3) + thischan.datashift = 4; + thischan.hold = (val >> 7) & 0x1; + break; + } + case 0x2: + thischan.pan = val & 0x7F; + break; + case 0x3: { + thischan.waveduty = val & 0x7; + thischan.repeat = (val >> 3) & 0x3; + thischan.format = (val >> 5) & 0x3; + thischan.status = (val >> 7) & 0x1; + if(thischan.status) + KeyOn((addr >> 4) & 0xF); + break; + } + } + +} + +extern "C" void SPU_WriteByte(struct NDS_state *state, u32 addr, u8 val) +{ + addr &= 0xFFF; + + if (addr < 0x500) + { + state->SPU_core->WriteByte(addr,val); + if(state->SPU_user) state->SPU_user->WriteByte(addr,val); + } + + T1WriteByte(state->MMU->ARM7_REG, addr, val); +} + +////////////////////////////////////////////////////////////////////////////// + +void SPU_struct::WriteWord(u32 addr, u16 val) +{ + channel_struct &thischan=channels[(addr >> 4) & 0xF]; + switch(addr & 0xF) + { + case 0x0: + thischan.vol = val & 0x7F; + thischan.datashift = (val >> 8) & 0x3; + if (thischan.datashift == 3) + thischan.datashift = 4; + thischan.hold = (val >> 15) & 0x1; + break; + case 0x2: + thischan.pan = val & 0x7F; + thischan.waveduty = (val >> 8) & 0x7; + thischan.repeat = (val >> 11) & 0x3; + thischan.format = (val >> 13) & 0x3; + thischan.status = (val >> 15) & 0x1; + if (thischan.status) + KeyOn((addr >> 4) & 0xF); + break; + case 0x8: + thischan.timer = val & 0xFFFF; + adjust_channel_timer(&thischan); + break; + case 0xA: + thischan.loopstart = val; + thischan.totlength = thischan.length + thischan.loopstart; + thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]); + break; + case 0xC: + WriteLong(addr,((u32)T1ReadWord(state->MMU->ARM7_REG, addr+2) << 16) | val); + break; + case 0xE: + WriteLong(addr,((u32)T1ReadWord(state->MMU->ARM7_REG, addr-2)) | ((u32)val<<16)); + break; + } +} + +extern "C" void SPU_WriteWord(NDS_state *state, u32 addr, u16 val) +{ + addr &= 0xFFF; + + if (addr < 0x500) + { + state->SPU_core->WriteWord(addr,val); + if(state->SPU_user) state->SPU_user->WriteWord(addr,val); + } + + T1WriteWord(state->MMU->ARM7_REG, addr, val); +} + +////////////////////////////////////////////////////////////////////////////// + +void SPU_struct::WriteLong(u32 addr, u32 val) +{ + channel_struct &thischan=channels[(addr >> 4) & 0xF]; + switch(addr & 0xF) + { + case 0x0: + thischan.vol = val & 0x7F; + thischan.datashift = (val >> 8) & 0x3; + if (thischan.datashift == 3) + thischan.datashift = 4; + thischan.hold = (val >> 15) & 0x1; + thischan.pan = (val >> 16) & 0x7F; + thischan.waveduty = (val >> 24) & 0x7; + thischan.repeat = (val >> 27) & 0x3; + thischan.format = (val >> 29) & 0x3; + thischan.status = (val >> 31) & 0x1; + if (thischan.status) + KeyOn((addr >> 4) & 0xF); + break; + case 0x4: + thischan.addr = val & 0x7FFFFFF; + break; + case 0x8: + thischan.timer = val & 0xFFFF; + thischan.loopstart = val >> 16; + adjust_channel_timer(&thischan); + break; + case 0xC: + thischan.length = val & 0x3FFFFF; + thischan.totlength = thischan.length + thischan.loopstart; + thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]); + break; + } +} + +extern "C" void SPU_WriteLong(NDS_state *state, u32 addr, u32 val) +{ + addr &= 0xFFF; + + if (addr < 0x500) + { + state->SPU_core->WriteLong(addr,val); + if(state->SPU_user) state->SPU_user->WriteLong(addr,val); + } + + T1WriteLong(state->MMU->ARM7_REG, addr, val); +} + +////////////////////////////////////////////////////////////////////////////// +static FORCEINLINE s32 Interpolate(SPUInterpolationMode INTERPOLATE_MODE, s32 a, s32 b, double ratio) +{ + if(INTERPOLATE_MODE == SPUInterpolation_Cosine) + { + //why did we change it away from the lookup table? somebody should research that + ratio = ratio - sputrunc(ratio); + double ratio2 = ((1.0 - cos(ratio * M_PI)) * 0.5); + //double ratio2 = (1.0f - cos_lut[((int)(ratio*256.0))&0xFF]) / 2.0f; + return s32floor((float)(((1-ratio2)*a) + (ratio2*b))); + } + else + { + //linear interpolation + ratio = ratio - sputrunc(ratio); + return s32floor((float)((1-ratio)*a + ratio*b)); + } +} + +////////////////////////////////////////////////////////////////////////////// +double round(double r) +{ + return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); +} + +static FORCEINLINE void Fetch8BitData(SPUInterpolationMode INTERPOLATE_MODE, channel_struct *chan, s32 *data) +{ + u32 loc = sputrunc(chan->sampcnt); + if(INTERPOLATE_MODE != SPUInterpolation_None) + { + s32 a = (s32)(chan->buf8[loc] << 8); + if(loc < (chan->totlength << 2) - 1) { + s32 b = (s32)(chan->buf8[loc + 1] << 8); + a = Interpolate(INTERPOLATE_MODE, a, b, chan->sampcnt); + } + *data = a; + } + else + *data = (s32)chan->buf8[loc] << 8; +} + +static FORCEINLINE void Fetch16BitData(SPUInterpolationMode INTERPOLATE_MODE, const channel_struct * const chan, s32 *data) +{ + const s16* const buf16 = chan->buf16; + const int shift = 1; + if(INTERPOLATE_MODE != SPUInterpolation_None) + { + u32 loc = sputrunc(chan->sampcnt); + s32 a = (s32)buf16[loc], b; + if(loc < (chan->totlength << shift) - 1) + { + b = (s32)buf16[loc + 1]; + a = Interpolate(INTERPOLATE_MODE,a, b, chan->sampcnt); + } + *data = a; + } + else + *data = (s32)buf16[sputrunc(chan->sampcnt)]; +} + +static FORCEINLINE void FetchADPCMData(SPUInterpolationMode INTERPOLATE_MODE, channel_struct * const chan, s32 * const data) +{ + // No sense decoding, just return the last sample + if (chan->lastsampcnt != sputrunc(chan->sampcnt)){ + + const u32 endExclusive = sputrunc(chan->sampcnt+1); + for (u32 i = chan->lastsampcnt+1; i < endExclusive; i++) + { + const u32 shift = (i&1)<<2; + const u32 data4bit = (((u32)chan->buf8[i >> 1]) >> shift); + + const s32 diff = precalcdifftbl[chan->index][data4bit & 0xF]; + chan->index = precalcindextbl[chan->index][data4bit & 0x7]; + + chan->pcm16b_last = chan->pcm16b; + chan->pcm16b = (s16)(MinMax(chan->pcm16b+diff, -0x8000, 0x7FFF)); + + if(i == (chan->loopstart<<3)) { + if(chan->loop_index != K_ADPCM_LOOPING_RECOVERY_INDEX) printf("over-snagging\n"); + chan->loop_pcm16b = chan->pcm16b; + chan->loop_index = chan->index; + } + } + + chan->lastsampcnt = sputrunc(chan->sampcnt); + } + + if(INTERPOLATE_MODE != SPUInterpolation_None) + *data = Interpolate(INTERPOLATE_MODE,(s32)chan->pcm16b_last,(s32)chan->pcm16b,chan->sampcnt); + else + *data = (s32)chan->pcm16b; +} + +static FORCEINLINE void FetchPSGData(channel_struct *chan, s32 *data) +{ + if(chan->num < 8) + { + *data = 0; + } + else if(chan->num < 14) + { + *data = (s32)wavedutytbl[chan->waveduty][(sputrunc(chan->sampcnt)) & 0x7]; + } + else + { + if(chan->lastsampcnt == sputrunc(chan->sampcnt)) + { + *data = (s32)chan->psgnoise_last; + return; + } + + u32 max = sputrunc(chan->sampcnt); + for(u32 i = chan->lastsampcnt; i < max; i++) + { + if(chan->x & 0x1) + { + chan->x = (chan->x >> 1); + chan->psgnoise_last = -0x7FFF; + } + else + { + chan->x = ((chan->x >> 1) ^ 0x6000); + chan->psgnoise_last = 0x7FFF; + } + } + + chan->lastsampcnt = sputrunc(chan->sampcnt); + + *data = (s32)chan->psgnoise_last; + } +} + +////////////////////////////////////////////////////////////////////////////// + +static FORCEINLINE void MixL(SPU_struct* SPU, channel_struct *chan, s32 data) +{ + data = spumuldiv7(data, chan->vol) >> chan->datashift; + SPU->sndbuf[SPU->bufpos<<1] += data; +} + +static FORCEINLINE void MixR(SPU_struct* SPU, channel_struct *chan, s32 data) +{ + data = spumuldiv7(data, chan->vol) >> chan->datashift; + SPU->sndbuf[(SPU->bufpos<<1)+1] += data; +} + +static FORCEINLINE void MixLR(SPU_struct* SPU, channel_struct *chan, s32 data) +{ + data = spumuldiv7(data, chan->vol) >> chan->datashift; + SPU->sndbuf[SPU->bufpos<<1] += spumuldiv7(data, 127 - chan->pan); + SPU->sndbuf[(SPU->bufpos<<1)+1] += spumuldiv7(data, chan->pan); +} + +////////////////////////////////////////////////////////////////////////////// + +static FORCEINLINE void TestForLoop(NDS_state *state, int FORMAT, SPU_struct *SPU, channel_struct *chan) +{ + const int shift = (FORMAT == 0 ? 2 : 1); + + chan->sampcnt += chan->sampinc; + + if (chan->sampcnt > chan->double_totlength_shifted) + { + // Do we loop? Or are we done? + if (chan->repeat == 1) + { + while (chan->sampcnt > chan->double_totlength_shifted) + chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << shift); + //chan->sampcnt = (double)(chan->loopstart << shift); + } + else + { + chan->status = CHANSTAT_STOPPED; + + if(SPU == state->SPU_core) + state->MMU->ARM7_REG[0x403 + (((chan-SPU->channels) ) * 0x10)] &= 0x7F; + SPU->bufpos = SPU->buflength; + } + } +} + +static FORCEINLINE void TestForLoop2(NDS_state *state, SPU_struct *SPU, channel_struct *chan) +{ + chan->sampcnt += chan->sampinc; + + if (chan->sampcnt > chan->double_totlength_shifted) + { + // Do we loop? Or are we done? + if (chan->repeat == 1) + { + while (chan->sampcnt > chan->double_totlength_shifted) + chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << 3); + + if(chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX) + { + chan->pcm16b = (s16)((chan->buf8[1] << 8) | chan->buf8[0]); + chan->index = chan->buf8[2] & 0x7F; + chan->lastsampcnt = 7; + } + else + { + chan->pcm16b = chan->loop_pcm16b; + chan->index = chan->loop_index; + chan->lastsampcnt = (chan->loopstart << 3); + } + } + else + { + chan->status = CHANSTAT_STOPPED; + if(SPU == state->SPU_core) + state->MMU->ARM7_REG[0x403 + (((chan-SPU->channels) ) * 0x10)] &= 0x7F; + SPU->bufpos = SPU->buflength; + } + } +} + +FORCEINLINE static void SPU_Mix(int CHANNELS, SPU_struct* SPU, channel_struct *chan, s32 data) +{ + switch(CHANNELS) + { + case 0: MixL(SPU, chan, data); break; + case 1: MixLR(SPU, chan, data); break; + case 2: MixR(SPU, chan, data); break; + } +} + +FORCEINLINE static void ____SPU_ChanUpdate(NDS_state *state, int CHANNELS, int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, SPU_struct* const SPU, channel_struct* const chan) +{ + for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) + { + if(CHANNELS != -1) + { + s32 data; + switch(FORMAT) + { + case 0: Fetch8BitData(INTERPOLATE_MODE, chan, &data); break; + case 1: Fetch16BitData(INTERPOLATE_MODE, chan, &data); break; + case 2: FetchADPCMData(INTERPOLATE_MODE, chan, &data); break; + case 3: FetchPSGData(chan, &data); break; + } + SPU_Mix(CHANNELS, SPU, chan, data); + } + + switch(FORMAT) { + case 0: case 1: TestForLoop(state, FORMAT, SPU, chan); break; + case 2: TestForLoop2(state, SPU, chan); break; + case 3: chan->sampcnt += chan->sampinc; break; + } + } +} + +FORCEINLINE static void ___SPU_ChanUpdate(NDS_state *state, int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan) +{ + if(!actuallyMix) + ____SPU_ChanUpdate(state,-1,FORMAT,INTERPOLATE_MODE,SPU,chan); + else if (chan->pan == 0) + ____SPU_ChanUpdate(state,0,FORMAT,INTERPOLATE_MODE,SPU,chan); + else if (chan->pan == 127) + ____SPU_ChanUpdate(state,2,FORMAT,INTERPOLATE_MODE,SPU,chan); + else + ____SPU_ChanUpdate(state,1,FORMAT,INTERPOLATE_MODE,SPU,chan); +} + +FORCEINLINE static void __SPU_ChanUpdate(NDS_state *state, SPUInterpolationMode INTERPOLATE_MODE, const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan) +{ + ___SPU_ChanUpdate(state,chan->format,INTERPOLATE_MODE,actuallyMix, SPU, chan); +} + +FORCEINLINE static void _SPU_ChanUpdate(NDS_state *state, const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan) +{ + __SPU_ChanUpdate(state, spuInterpolationMode(state),actuallyMix, SPU, chan); +} + + +static void SPU_MixAudio(NDS_state *state, bool actuallyMix, SPU_struct *SPU, int length) +{ + u8 vol; + + if(actuallyMix) + { + memset(SPU->sndbuf, 0, length*4*2); + memset(SPU->outbuf, 0, length*2*2); + } + + //---not appropriate for 2sf player + // If the sound speakers are disabled, don't output audio + //if(!(T1ReadWord(MMU->ARM7_REG, 0x304) & 0x01)) + // return; + + // If Master Enable isn't set, don't output audio + //if (!(T1ReadByte(MMU->ARM7_REG, 0x501) & 0x80)) + // return; + //------------------------ + + vol = T1ReadByte(state->MMU->ARM7_REG, 0x500) & 0x7F; + + for(int i=0;i<16;i++) + { + channel_struct *chan = &SPU->channels[i]; + + if (chan->status != CHANSTAT_PLAY) + continue; + + SPU->bufpos = 0; + SPU->buflength = length; + + // Mix audio + _SPU_ChanUpdate(state, !isChannelMuted(state, i) && actuallyMix, SPU, chan); + } + + // convert from 32-bit->16-bit + if(actuallyMix) + for (int i = 0; i < length*2; i++) + { + // Apply Master Volume + SPU->sndbuf[i] = spumuldiv7(SPU->sndbuf[i], vol); + + if (SPU->sndbuf[i] > 0x7FFF) + SPU->outbuf[i] = 0x7FFF; + else if (SPU->sndbuf[i] < -0x8000) + SPU->outbuf[i] = -0x8000; + else + SPU->outbuf[i] = (s16)SPU->sndbuf[i]; + } +} + +////////////////////////////////////////////////////////////////////////////// + + +//emulates one hline of the cpu core. +//this will produce a variable number of samples, calculated to keep a 44100hz output +//in sync with the emulator framerate +static const int dots_per_clock = 6; +static const int dots_per_hline = 355; +static const double time_per_hline = (double)1.0/((double)ARM7_CLOCK/dots_per_clock/dots_per_hline); +static const double samples_per_hline = time_per_hline * 44100; +void SPU_Emulate_core(NDS_state *state) +{ + state->samples += samples_per_hline; + state->spu_core_samples = (int)(state->samples); + state->samples -= state->spu_core_samples; + + //TODO + /*if(driver->AVI_IsRecording() || driver->WAV_IsRecording()) + SPU_MixAudio(SPU_core,spu_core_samples); + else + SPU_MixAudio(SPU_core,spu_core_samples);*/ +} + +extern "C" void SPU_EmulateSamples(NDS_state *state, int numsamples) +{ + SPU_MixAudio(state,true,state->SPU_core,numsamples); + state->SNDCore->UpdateAudio(state,state->SPU_core->outbuf,numsamples); +} + +extern "C" void SPU_Emulate_user(NDS_state *state, BOOL mix) +{ + if(!state->SPU_user) + return; + + u32 audiosize; + + // Check to see how much free space there is + // If there is some, fill up the buffer + audiosize = state->SNDCore->GetAudioSpace(state); + + if (audiosize > 0) + { + //printf("mix %i samples\n", audiosize); + if (audiosize > state->SPU_user->bufsize) + audiosize = state->SPU_user->bufsize; + if (mix) SPU_MixAudio(state,true,state->SPU_user,audiosize); + state->SNDCore->UpdateAudio(state,state->SPU_user->outbuf, audiosize); + } +} + +////////////////////////////////////////////////////////////////////////////// +// Dummy Sound Interface +////////////////////////////////////////////////////////////////////////////// + +int SNDDummyInit(NDS_state *, int buffersize); +void SNDDummyDeInit(NDS_state *); +void SNDDummyUpdateAudio(NDS_state *, s16 *buffer, u32 num_samples); +u32 SNDDummyGetAudioSpace(NDS_state *); +void SNDDummyMuteAudio(NDS_state *); +void SNDDummyUnMuteAudio(NDS_state *); +void SNDDummySetVolume(NDS_state *, int volume); + +SoundInterface_struct SNDDummy = { + SNDCORE_DUMMY, + "Dummy Sound Interface", + SNDDummyInit, + SNDDummyDeInit, + SNDDummyUpdateAudio, + SNDDummyGetAudioSpace, + SNDDummyMuteAudio, + SNDDummyUnMuteAudio, + SNDDummySetVolume +}; + +////////////////////////////////////////////////////////////////////////////// + +int SNDDummyInit(NDS_state *, int buffersize) +{ + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +void SNDDummyDeInit(NDS_state *) +{ +} + +////////////////////////////////////////////////////////////////////////////// + +void SNDDummyUpdateAudio(NDS_state *, s16 *buffer, u32 num_samples) +{ +} + +////////////////////////////////////////////////////////////////////////////// + +u32 SNDDummyGetAudioSpace(NDS_state *) +{ + return 740; +} + +////////////////////////////////////////////////////////////////////////////// + +void SNDDummyMuteAudio(NDS_state *) +{ +} + +////////////////////////////////////////////////////////////////////////////// + +void SNDDummyUnMuteAudio(NDS_state *) +{ +} + +////////////////////////////////////////////////////////////////////////////// + +void SNDDummySetVolume(NDS_state *, int volume) +{ +} + +////////////////////////////////////////////////////////////////////////////// +// +//typedef struct { +// char id[4]; +// u32 size; +//} chunk_struct; +// +//typedef struct { +// chunk_struct riff; +// char rifftype[4]; +//} waveheader_struct; +// +//typedef struct { +// chunk_struct chunk; +// u16 compress; +// u16 numchan; +// u32 rate; +// u32 bytespersec; +// u16 blockalign; +// u16 bitspersample; +//} fmt_struct; +// +//WavWriter::WavWriter() +//: spufp(NULL) +//{ +//} +//bool WavWriter::open(const std::string & fname) +//{ +// waveheader_struct waveheader; +// fmt_struct fmt; +// chunk_struct data; +// size_t elems_written = 0; +// +// if ((spufp = fopen(fname.c_str(), "wb")) == NULL) +// return false; +// +// // Do wave header +// memcpy(waveheader.riff.id, "RIFF", 4); +// waveheader.riff.size = 0; // we'll fix this after the file is closed +// memcpy(waveheader.rifftype, "WAVE", 4); +// elems_written += fwrite((void *)&waveheader, 1, sizeof(waveheader_struct), spufp); +// +// // fmt chunk +// memcpy(fmt.chunk.id, "fmt ", 4); +// fmt.chunk.size = 16; // we'll fix this at the end +// fmt.compress = 1; // PCM +// fmt.numchan = 2; // Stereo +// fmt.rate = 44100; +// fmt.bitspersample = 16; +// fmt.blockalign = fmt.bitspersample / 8 * fmt.numchan; +// fmt.bytespersec = fmt.rate * fmt.blockalign; +// elems_written += fwrite((void *)&fmt, 1, sizeof(fmt_struct), spufp); +// +// // data chunk +// memcpy(data.id, "data", 4); +// data.size = 0; // we'll fix this at the end +// elems_written += fwrite((void *)&data, 1, sizeof(chunk_struct), spufp); +// +// return true; +//} +// +//void WavWriter::close() +//{ +// if(!spufp) return; +// size_t elems_written = 0; +// long length = ftell(spufp); +// +// // Let's fix the riff chunk size and the data chunk size +// fseek(spufp, sizeof(waveheader_struct)-0x8, SEEK_SET); +// length -= 0x8; +// elems_written += fwrite((void *)&length, 1, 4, spufp); +// +// fseek(spufp, sizeof(waveheader_struct)+sizeof(fmt_struct)+0x4, SEEK_SET); +// length -= sizeof(waveheader_struct)+sizeof(fmt_struct); +// elems_written += fwrite((void *)&length, 1, 4, spufp); +// fclose(spufp); +// spufp = NULL; +//} +// +//void WavWriter::update(void* soundData, int numSamples) +//{ +// if(!spufp) return; +// //TODO - big endian for the s16 samples?? +// size_t elems_written = fwrite(soundData, numSamples*2, 2, spufp); +//} +// +//bool WavWriter::isRecording() const +//{ +// return spufp != NULL; +//} +// +// +//static WavWriter wavWriter; +// +//void WAV_End() +//{ +// wavWriter.close(); +//} +// +//bool WAV_Begin(const char* fname) +//{ +// WAV_End(); +// +// if(!wavWriter.open(fname)) +// return false; +// +// driver->USR_InfoMessage("WAV recording started."); +// +// return true; +//} +// +//bool WAV_IsRecording() +//{as +// return wavWriter.isRecording(); +//} +// +//void WAV_WavSoundUpdate(void* soundData, int numSamples) +//{ +// wavWriter.update(soundData, numSamples); +//} +// diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/SPU.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/SPU.h new file mode 100755 index 000000000..284763683 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/SPU.h @@ -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 +#include "types.h" +#include +#include + +#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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/arm_instructions.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/arm_instructions.c new file mode 100755 index 000000000..dacfb94f7 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/arm_instructions.c @@ -0,0 +1,7926 @@ +/* Copyright (C) 2006 yopyop + Copyright (C) 2006 shash + yopyop156@ifrance.com + yopyop156.ifrance.com + + 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 "cp15.h" +#include "debug.h" +#include "MMU.h" + + +// 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 + + + +#define LSL_IMM shift_op = cpu->R[REG_POS(i,0)]<<((i>>7)&0x1F); + +#define S_LSL_IMM u32 shift_op = ((i>>7)&0x1F);\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], 32-shift_op);\ + shift_op = cpu->R[REG_POS(i,0)]<<((i>>7)&0x1F);\ + } + +#define LSL_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + if(shift_op>=32)\ + shift_op=0;\ + else\ + shift_op=cpu->R[REG_POS(i,0)]<R[REG_POS(i,8)])&0xFF;\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + if(shift_op<32)\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], 32-shift_op);\ + shift_op = cpu->R[REG_POS(i,0)]<R[REG_POS(i,0)]);\ + }\ + else\ + {\ + shift_op = 0;\ + c = 0;\ + } + +#define LSR_IMM shift_op = ((i>>7)&0x1F);\ + if(shift_op!=0)\ + shift_op = cpu->R[REG_POS(i,0)]>>shift_op; + +#define S_LSR_IMM u32 shift_op = ((i>>7)&0x1F);\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + {\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + }\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = cpu->R[REG_POS(i,0)]>>shift_op;\ + } + +#define LSR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + if(shift_op>=32)\ + shift_op = 0;\ + else\ + shift_op = cpu->R[REG_POS(i,0)]>>shift_op; + +#define S_LSR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + {\ + shift_op = cpu->R[REG_POS(i,0)];\ + }\ + else\ + if(shift_op<32)\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = cpu->R[REG_POS(i,0)]>>shift_op;\ + }\ + else\ + if(shift_op==32)\ + {\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + shift_op = 0;\ + }\ + else\ + {\ + c = 0;\ + shift_op = 0;\ + } + +#define ASR_IMM shift_op = ((i>>7)&0x1F);\ + if(shift_op==0)\ + shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\ + else\ + shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op); + +#define S_ASR_IMM u32 shift_op = ((i>>7)&0x1F);\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + {\ + shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + }\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\ + } + +#define ASR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + if(shift_op<32)\ + shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\ + else\ + shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF; + +#define S_ASR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + if(shift_op<32)\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\ + }\ + else\ + {\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\ + } + +#define ROR_IMM shift_op = ((i>>7)&0x1F);\ + if(shift_op==0)\ + {\ + u32 tmp = cpu->CPSR.bits.C;\ + shift_op = (tmp<<31)|(cpu->R[REG_POS(i,0)]>>1);\ + }\ + else\ + shift_op = ROR(cpu->R[REG_POS(i,0)],shift_op); + +#define S_ROR_IMM u32 shift_op = ((i>>7)&0x1F);\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + {\ + u32 tmp = cpu->CPSR.bits.C;\ + shift_op = (tmp<<31)|(cpu->R[REG_POS(i,0)]>>1);\ + c = BIT0(cpu->R[REG_POS(i,0)]);\ + }\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = ROR(cpu->R[REG_POS(i,0)],shift_op);\ + } + +#define ROR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + if((shift_op==0)||((shift_op&0xF)==0))\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + shift_op = ROR(cpu->R[REG_POS(i,0)],(shift_op&0xF)); + +#define S_ROR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + {\ + shift_op&=0xF;\ + if(shift_op==0)\ + {\ + shift_op=cpu->R[REG_POS(i,0)];\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + }\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = ROR(cpu->R[REG_POS(i,0)],(shift_op&0xF));\ + }\ + } + +#define IMM_VALUE u32 shift_op = ROR((i&0xFF), (i>>7)&0x1E); + +#define S_IMM_VALUE u32 shift_op = ROR((i&0xFF), (i>>7)&0x1E);\ + u32 c = cpu->CPSR.bits.C;\ + if((i>>8)&0xF)\ + c = BIT31(shift_op); + +#define IMM_OFF (((i>>4)&0xF0)+(i&0xF)) + +#define IMM_OFF_12 ((i)&0xFFF) + +static u32 FASTCALL OP_UND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LOG("Undefined instruction: %08X\n", i); + cpu->state->execute = FALSE; + return 1; +} + +//-----------------------AND------------------------------------ + +#define OP_AND(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OP_ANDS(a, b)\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR;\ + cpu->R[15] = cpu->R[REG_POS(i,16)] & shift_op;\ + SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & shift_op;\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a; + +static u32 FASTCALL OP_AND_LSL_IMM(register armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_AND(1, 3); +} + +static u32 FASTCALL OP_AND_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_AND(2, 4); +} + +static u32 FASTCALL OP_AND_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_AND(1, 3); +} + +static u32 FASTCALL OP_AND_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_AND(2, 4); +} + +static u32 FASTCALL OP_AND_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_AND(1, 3); +} + +static u32 FASTCALL OP_AND_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_AND(2, 4); +} + +static u32 FASTCALL OP_AND_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_AND(1, 3); +} + +static u32 FASTCALL OP_AND_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_AND(2, 4); +} + +static u32 FASTCALL OP_AND_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_AND(1, 3); +} + +static u32 FASTCALL OP_AND_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_ANDS(2, 4); +} + +static u32 FASTCALL OP_AND_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_ANDS(3, 5); +} + +static u32 FASTCALL OP_AND_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_ANDS(2, 4); +} + +static u32 FASTCALL OP_AND_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_ANDS(3, 5); +} + +static u32 FASTCALL OP_AND_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_ANDS(2, 4); +} + +static u32 FASTCALL OP_AND_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_ANDS(3, 5); +} + +static u32 FASTCALL OP_AND_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_ANDS(2, 4); +} + +static u32 FASTCALL OP_AND_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_ANDS(3, 5); +} + +static u32 FASTCALL OP_AND_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_ANDS(2, 4); +} + +//--------------EOR------------------------------ + +#define OP_EOR(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] ^ shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OP_EORS(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] ^ shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a; + +static u32 FASTCALL OP_EOR_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_EOR(1, 3); +} + +static u32 FASTCALL OP_EOR_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_EOR(2, 4); +} + +static u32 FASTCALL OP_EOR_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_EOR(1, 3); +} + +static u32 FASTCALL OP_EOR_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_EOR(2, 4); +} + +static u32 FASTCALL OP_EOR_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_EOR(1, 3); +} + +static u32 FASTCALL OP_EOR_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_EOR(2, 4); +} + +static u32 FASTCALL OP_EOR_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_EOR(1, 3); +} + +static u32 FASTCALL OP_EOR_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_EOR(2, 4); +} + +static u32 FASTCALL OP_EOR_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_EOR(1, 3); +} + +static u32 FASTCALL OP_EOR_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_EORS(2, 4); +} + +static u32 FASTCALL OP_EOR_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_EORS(3, 5); +} + +static u32 FASTCALL OP_EOR_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_EORS(2, 4); +} + +static u32 FASTCALL OP_EOR_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_EORS(3, 5); +} + +static u32 FASTCALL OP_EOR_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_EORS(2, 4); +} + +static u32 FASTCALL OP_EOR_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_EORS(3, 5); +} + +static u32 FASTCALL OP_EOR_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_EORS(2, 4); +} + +static u32 FASTCALL OP_EOR_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_EORS(3, 5); +} + +static u32 FASTCALL OP_EOR_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_EORS(2, 4); +} + +//-------------SUB------------------------------------- + +#define OP_SUB(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] - shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OPSUBS(a, b) cpu->R[REG_POS(i,12)] = v - shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\ + return a; + +static u32 FASTCALL OP_SUB_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_SUB(1, 3); +} + +static u32 FASTCALL OP_SUB_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_SUB(2, 4); +} + +static u32 FASTCALL OP_SUB_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_SUB(1, 3); +} + +static u32 FASTCALL OP_SUB_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_SUB(2, 4); +} + +static u32 FASTCALL OP_SUB_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_SUB(1, 3); +} + +static u32 FASTCALL OP_SUB_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_SUB(2, 4); +} + +static u32 FASTCALL OP_SUB_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_SUB(1, 3); +} + +static u32 FASTCALL OP_SUB_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_SUB(2, 4); +} + +static u32 FASTCALL OP_SUB_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_SUB(1, 3); +} + +static u32 FASTCALL OP_SUB_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSL_IMM; + OPSUBS(2, 4); +} + +static u32 FASTCALL OP_SUB_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OPSUBS(3, 5); +} + +static u32 FASTCALL OP_SUB_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSR_IMM; + OPSUBS(2, 4); +} + +static u32 FASTCALL OP_SUB_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OPSUBS(3, 5); +} + +static u32 FASTCALL OP_SUB_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ASR_IMM; + OPSUBS(2, 4); +} + +static u32 FASTCALL OP_SUB_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OPSUBS(3, 5); +} + +static u32 FASTCALL OP_SUB_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ROR_IMM; + OPSUBS(2, 4); +} + +static u32 FASTCALL OP_SUB_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OPSUBS(3, 5); +} + +static u32 FASTCALL OP_SUB_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OPSUBS(2, 4); +} + +//------------------RSB------------------------ + +#define OP_RSB(a, b) cpu->R[REG_POS(i,12)] = shift_op - cpu->R[REG_POS(i,16)];\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OP_RSBS(a, b) cpu->R[REG_POS(i,12)] = shift_op - v;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(shift_op, v, cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(shift_op, v, cpu->R[REG_POS(i,12)]);\ + return a; + +static u32 FASTCALL OP_RSB_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_RSB(1, 3); +} + +static u32 FASTCALL OP_RSB_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_RSB(2, 4); +} + +static u32 FASTCALL OP_RSB_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_RSB(1, 3); +} + +static u32 FASTCALL OP_RSB_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_RSB(2, 4); +} + +static u32 FASTCALL OP_RSB_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_RSB(1, 3); +} + +static u32 FASTCALL OP_RSB_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_RSB(2, 4); +} + +static u32 FASTCALL OP_RSB_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_RSB(1, 3); +} + +static u32 FASTCALL OP_RSB_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_RSB(2, 4); +} + +static u32 FASTCALL OP_RSB_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_RSB(1, 3); +} + +static u32 FASTCALL OP_RSB_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSL_IMM; + OP_RSBS(2, 4); +} + +static u32 FASTCALL OP_RSB_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_RSBS(3, 5); +} + +static u32 FASTCALL OP_RSB_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSR_IMM; + OP_RSBS(2, 4); +} + +static u32 FASTCALL OP_RSB_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_RSBS(3, 5); +} + +static u32 FASTCALL OP_RSB_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ASR_IMM; + OP_RSBS(2, 4); +} + +static u32 FASTCALL OP_RSB_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_RSBS(3, 5); +} + +static u32 FASTCALL OP_RSB_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ROR_IMM; + OP_RSBS(2, 4); +} + +static u32 FASTCALL OP_RSB_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_RSBS(3, 5); +} + +static u32 FASTCALL OP_RSB_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_RSBS(2, 4); +} + +//------------------ADD----------------------------------- + +#define OP_ADD(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] + shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +static u32 FASTCALL OP_ADD_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_ADD(1, 3); +} + +static u32 FASTCALL OP_ADD_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_ADD(2, 4); +} + +static u32 FASTCALL OP_ADD_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_ADD(1, 3); +} + +static u32 FASTCALL OP_ADD_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_ADD(2, 4); +} + +static u32 FASTCALL OP_ADD_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_ADD(1, 3); +} + +static u32 FASTCALL OP_ADD_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_ADD(2, 4); +} + +static u32 FASTCALL OP_ADD_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_ADD(1, 3); +} + +static u32 FASTCALL OP_ADD_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_ADD(2, 4); +} + +static u32 FASTCALL OP_ADD_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_ADD(1, 3); +} + +#define OP_ADDS(a, b) cpu->R[REG_POS(i,12)] = v + shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.V = SIGNED_OVERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\ + return a; + +static u32 FASTCALL OP_ADD_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSL_IMM; + OP_ADDS(2, 4); +} + +static u32 FASTCALL OP_ADD_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_ADDS(3, 5); +} + +static u32 FASTCALL OP_ADD_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSR_IMM; + OP_ADDS(2, 4); +} + +static u32 FASTCALL OP_ADD_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_ADDS(3, 5); +} + +static u32 FASTCALL OP_ADD_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ASR_IMM; + OP_ADDS(2, 4); +} + +static u32 FASTCALL OP_ADD_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_ADDS(3, 5); +} + +static u32 FASTCALL OP_ADD_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ROR_IMM; + OP_ADDS(2, 4); +} + +static u32 FASTCALL OP_ADD_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_ADDS(3, 5); +} + +static u32 FASTCALL OP_ADD_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_ADDS(2, 4); +} + +//------------------ADC----------------------------------- + +#define OP_ADC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] + shift_op + cpu->CPSR.bits.C;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +static u32 FASTCALL OP_ADC_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_ADC(1, 3); +} + +static u32 FASTCALL OP_ADC_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_ADC(2, 4); +} + +static u32 FASTCALL OP_ADC_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_ADC(1, 3); +} + +static u32 FASTCALL OP_ADC_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_ADC(2, 4); +} + +static u32 FASTCALL OP_ADC_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_ADC(1, 3); +} + +static u32 FASTCALL OP_ADC_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_ADC(2, 4); +} + +static u32 FASTCALL OP_ADC_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_ADC(1, 3); +} + +static u32 FASTCALL OP_ADC_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_ADC(2, 4); +} + +static u32 FASTCALL OP_ADC_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_ADC(1, 3); +} + +#define OP_ADCS(a, b) \ + { \ + u32 tmp = shift_op + cpu->CPSR.bits.C;\ + cpu->R[REG_POS(i,12)] = v + tmp;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(shift_op, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(v, tmp, cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.V = SIGNED_OVERFLOW(shift_op, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(v, tmp, cpu->R[REG_POS(i,12)]);\ + return a; \ + } + +static u32 FASTCALL OP_ADC_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSL_IMM; + OP_ADCS(2, 4); +} + +static u32 FASTCALL OP_ADC_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_ADCS(3, 5); +} + +static u32 FASTCALL OP_ADC_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSR_IMM; + OP_ADCS(2, 4); +} + +static u32 FASTCALL OP_ADC_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_ADCS(3, 5); +} + +static u32 FASTCALL OP_ADC_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ASR_IMM; + OP_ADCS(2, 4); +} + +static u32 FASTCALL OP_ADC_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_ADCS(3, 5); +} + +static u32 FASTCALL OP_ADC_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ROR_IMM; + OP_ADCS(2, 4); +} + +static u32 FASTCALL OP_ADC_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_ADCS(3, 5); +} + +static u32 FASTCALL OP_ADC_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_ADCS(2, 4); +} + +//-------------SBC------------------------------------- + +#define OP_SBC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] - shift_op - (!cpu->CPSR.bits.C);\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +static u32 FASTCALL OP_SBC_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_SBC(1, 3); +} + +static u32 FASTCALL OP_SBC_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_SBC(2, 4); +} + +static u32 FASTCALL OP_SBC_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_SBC(1, 3); +} + +static u32 FASTCALL OP_SBC_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_SBC(2, 4); +} + +static u32 FASTCALL OP_SBC_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_SBC(1, 3); +} + +static u32 FASTCALL OP_SBC_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_SBC(2, 4); +} + +static u32 FASTCALL OP_SBC_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_SBC(1, 3); +} + +static u32 FASTCALL OP_SBC_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_SBC(2, 4); +} + +static u32 FASTCALL OP_SBC_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_SBC(1, 3); +} + +#define OP_SBCS(a, b) \ + { \ + u32 tmp = v - (!cpu->CPSR.bits.C);\ + cpu->R[REG_POS(i,12)] = tmp - shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(v, (!cpu->CPSR.bits.C), tmp)) & (!UNSIGNED_UNDERFLOW(tmp, shift_op, cpu->R[REG_POS(i,12)]));\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(v, (!cpu->CPSR.bits.C), tmp) | SIGNED_UNDERFLOW(tmp, shift_op, cpu->R[REG_POS(i,12)]);\ + return a; \ + } + +static u32 FASTCALL OP_SBC_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSL_IMM; + OP_SBCS(2, 4); +} + +static u32 FASTCALL OP_SBC_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_SBCS(3, 5); +} + +static u32 FASTCALL OP_SBC_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSR_IMM; + OP_SBCS(2, 4); +} + +static u32 FASTCALL OP_SBC_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_SBCS(3, 5); +} + +static u32 FASTCALL OP_SBC_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ASR_IMM; + OP_SBCS(2, 4); +} + +static u32 FASTCALL OP_SBC_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_SBCS(3, 5); +} + +static u32 FASTCALL OP_SBC_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ROR_IMM; + OP_SBCS(2, 4); +} + +static u32 FASTCALL OP_SBC_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_SBCS(3, 5); +} + +static u32 FASTCALL OP_SBC_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_SBCS(2, 4); +} + +//---------------RSC---------------------------------- + +#define OP_RSC(a, b) cpu->R[REG_POS(i,12)] = shift_op - cpu->R[REG_POS(i,16)] - (!cpu->CPSR.bits.C);\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +static u32 FASTCALL OP_RSC_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_RSC(1, 3); +} + +static u32 FASTCALL OP_RSC_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_RSC(2, 4); +} + +static u32 FASTCALL OP_RSC_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_RSC(1, 3); +} + +static u32 FASTCALL OP_RSC_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_RSC(2, 4); +} + +static u32 FASTCALL OP_RSC_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_RSC(1, 3); +} + +static u32 FASTCALL OP_RSC_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_RSC(2, 4); +} + +static u32 FASTCALL OP_RSC_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_RSC(1, 3); +} + +static u32 FASTCALL OP_RSC_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_RSC(2, 4); +} + +static u32 FASTCALL OP_RSC_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_RSC(1, 3); +} + +#define OP_RSCS(a,b) \ + { \ + u32 tmp = shift_op - (!cpu->CPSR.bits.C);\ + cpu->R[REG_POS(i,12)] = tmp - v;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(shift_op, (!cpu->CPSR.bits.C), tmp)) & (!UNSIGNED_UNDERFLOW(tmp, v, cpu->R[REG_POS(i,12)]));\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(shift_op, (!cpu->CPSR.bits.C), tmp) | SIGNED_UNDERFLOW(tmp, v, cpu->R[REG_POS(i,12)]);\ + return a; \ + } + +static u32 FASTCALL OP_RSC_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSL_IMM; + OP_RSCS(2,4); +} + +static u32 FASTCALL OP_RSC_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_RSCS(3,5); +} + +static u32 FASTCALL OP_RSC_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + LSR_IMM; + OP_RSCS(2,4); +} + +static u32 FASTCALL OP_RSC_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_RSCS(3,5); +} + +static u32 FASTCALL OP_RSC_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ASR_IMM; + OP_RSCS(2,4); +} + +static u32 FASTCALL OP_RSC_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_RSCS(3,5); +} + +static u32 FASTCALL OP_RSC_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + u32 shift_op; + ROR_IMM; + OP_RSCS(2,4); +} + +static u32 FASTCALL OP_RSC_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_RSCS(3,5); +} + +static u32 FASTCALL OP_RSC_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_RSCS(2,4); +} + +//-------------------TST---------------------------- + +#define OP_TST(a) \ + { \ + unsigned tmp = cpu->R[REG_POS(i,16)] & shift_op;\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(tmp);\ + cpu->CPSR.bits.Z = (tmp==0);\ + return a; \ + } + +static u32 FASTCALL OP_TST_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_TST(1); +} + +static u32 FASTCALL OP_TST_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_TST(2); +} + +static u32 FASTCALL OP_TST_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_TST(1); +} + +static u32 FASTCALL OP_TST_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_TST(2); +} + +static u32 FASTCALL OP_TST_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_TST(1); +} + +static u32 FASTCALL OP_TST_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_TST(2); +} + +static u32 FASTCALL OP_TST_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_TST(1); +} + +static u32 FASTCALL OP_TST_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_TST(2); +} + +static u32 FASTCALL OP_TST_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_TST(1); +} + +//-------------------TEQ---------------------------- + +#define OP_TEQ(a) \ + { \ + unsigned tmp = cpu->R[REG_POS(i,16)] ^ shift_op;\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(tmp);\ + cpu->CPSR.bits.Z = (tmp==0);\ + return a; \ + } + +static u32 FASTCALL OP_TEQ_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_TEQ(1); +} + +static u32 FASTCALL OP_TEQ_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_TEQ(2); +} + +static u32 FASTCALL OP_TEQ_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_TEQ(1); +} + +static u32 FASTCALL OP_TEQ_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_TEQ(2); +} + +static u32 FASTCALL OP_TEQ_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_TEQ(1); +} + +static u32 FASTCALL OP_TEQ_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_TEQ(2); +} + +static u32 FASTCALL OP_TEQ_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_TEQ(1); +} + +static u32 FASTCALL OP_TEQ_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_TEQ(2); +} + +static u32 FASTCALL OP_TEQ_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_TEQ(1); +} + +//-------------CMP------------------------------------- + +#define OP_CMP(a) \ + { \ + u32 tmp = cpu->R[REG_POS(i,16)] - shift_op;\ + cpu->CPSR.bits.N = BIT31(tmp);\ + cpu->CPSR.bits.Z = (tmp==0);\ + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\ + return a; \ + } + +static u32 FASTCALL OP_CMP_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_CMP(1); +} + +static u32 FASTCALL OP_CMP_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_CMP(2); +} + +static u32 FASTCALL OP_CMP_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_CMP(1); +} + +static u32 FASTCALL OP_CMP_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_CMP(2); +} + +static u32 FASTCALL OP_CMP_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_CMP(1); +} + +static u32 FASTCALL OP_CMP_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_CMP(2); +} + +static u32 FASTCALL OP_CMP_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_CMP(1); +} + +static u32 FASTCALL OP_CMP_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_CMP(2); +} + +static u32 FASTCALL OP_CMP_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_CMP(1); +} + +//---------------CMN--------------------------- + +#define OP_CMN(a) \ + { \ + u32 tmp = cpu->R[REG_POS(i,16)] + shift_op;\ + cpu->CPSR.bits.N = BIT31(tmp);\ + cpu->CPSR.bits.Z = (tmp==0);\ + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\ + cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\ + return a; \ + } + +static u32 FASTCALL OP_CMN_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_CMN(1); +} + +static u32 FASTCALL OP_CMN_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_CMN(2); +} + +static u32 FASTCALL OP_CMN_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_CMN(1); +} + +static u32 FASTCALL OP_CMN_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_CMN(2); +} + +static u32 FASTCALL OP_CMN_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_CMN(1); +} + +static u32 FASTCALL OP_CMN_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_CMN(2); +} + +static u32 FASTCALL OP_CMN_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_CMN(1); +} + +static u32 FASTCALL OP_CMN_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_CMN(2); +} + +static u32 FASTCALL OP_CMN_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_CMN(1); +} + +//------------------ORR------------------- + +#define OP_ORR(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +static u32 FASTCALL OP_ORR_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_ORR(1, 3); +} + +static u32 FASTCALL OP_ORR_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_ORR(2, 4); +} + +static u32 FASTCALL OP_ORR_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_ORR(1, 3); +} + +static u32 FASTCALL OP_ORR_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_ORR(2, 4); +} + +static u32 FASTCALL OP_ORR_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_ORR(1, 3); +} + +static u32 FASTCALL OP_ORR_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_ORR(2, 4); +} + +static u32 FASTCALL OP_ORR_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_ORR(1, 3); +} + +static u32 FASTCALL OP_ORR_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_ORR(2, 4); +} + +static u32 FASTCALL OP_ORR_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_ORR(1, 3); +} + +static u32 FASTCALL OP_ORR_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +static u32 FASTCALL OP_ORR_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 5; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 3; +} + +static u32 FASTCALL OP_ORR_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +static u32 FASTCALL OP_ORR_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 5; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 3; +} + +static u32 FASTCALL OP_ORR_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +static u32 FASTCALL OP_ORR_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 5; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 3; +} + +static u32 FASTCALL OP_ORR_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +static u32 FASTCALL OP_ORR_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 5; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 3; +} + +static u32 FASTCALL OP_ORR_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +//------------------MOV------------------- + +#define OP_MOV(a, b) cpu->R[REG_POS(i,12)] = shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = shift_op;\ + return b;\ + }\ + return a; + +#define OP_MOV_S(a, b) cpu->R[REG_POS(i,12)] = shift_op;\ + if(BIT20(i) && REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a;\ + +static u32 FASTCALL OP_MOV_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OP_MOV(1,3); +} + +static u32 FASTCALL OP_MOV_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + if (REG_POS(i,0) == 15) shift_op += 4; + OP_MOV(2,4); +} + +static u32 FASTCALL OP_MOV_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OP_MOV(1,3); +} + +static u32 FASTCALL OP_MOV_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + if (REG_POS(i,0) == 15) shift_op += 4; + OP_MOV(2,4); +} + +static u32 FASTCALL OP_MOV_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OP_MOV(1,3); +} + +static u32 FASTCALL OP_MOV_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_MOV(2,4); +} + +static u32 FASTCALL OP_MOV_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OP_MOV(2,4); +} + +static u32 FASTCALL OP_MOV_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_MOV(2,4); +} + +static u32 FASTCALL OP_MOV_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_MOV(1,3); +} + +static u32 FASTCALL OP_MOV_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_MOV_S(2,4); +} + +static u32 FASTCALL OP_MOV_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + if (REG_POS(i,0) == 15) shift_op += 4; + OP_MOV_S(3,5); +} + +static u32 FASTCALL OP_MOV_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_MOV_S(2,4); +} + +static u32 FASTCALL OP_MOV_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + if (REG_POS(i,0) == 15) shift_op += 4; + OP_MOV_S(3,5); +} + +static u32 FASTCALL OP_MOV_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_MOV_S(2,4); +} + +static u32 FASTCALL OP_MOV_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_MOV_S(3,5); +} + +static u32 FASTCALL OP_MOV_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_MOV_S(2,4); +} + +static u32 FASTCALL OP_MOV_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_MOV_S(3,5); +} + +static u32 FASTCALL OP_MOV_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_MOV_S(2,4); +} + +//------------------BIC------------------- +#define OPP_BIC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & (~shift_op);\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OPP_BIC_S(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & (~shift_op);\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a; + +static u32 FASTCALL OP_BIC_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OPP_BIC(1,3); +} + +static u32 FASTCALL OP_BIC_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OPP_BIC(2,4); +} + +static u32 FASTCALL OP_BIC_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OPP_BIC(1,3); +} + +static u32 FASTCALL OP_BIC_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OPP_BIC(2,4); +} + +static u32 FASTCALL OP_BIC_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OPP_BIC(1,3); +} + +static u32 FASTCALL OP_BIC_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OPP_BIC(2,4); +} + +static u32 FASTCALL OP_BIC_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OPP_BIC(1,3); +} + +static u32 FASTCALL OP_BIC_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OPP_BIC(2,4); +} + +static u32 FASTCALL OP_BIC_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OPP_BIC(1,3); +} + +static u32 FASTCALL OP_BIC_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OPP_BIC_S(2,4); +} + +static u32 FASTCALL OP_BIC_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OPP_BIC_S(3,5); +} + +static u32 FASTCALL OP_BIC_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OPP_BIC_S(2,4); +} + +static u32 FASTCALL OP_BIC_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OPP_BIC_S(3,5); +} + +static u32 FASTCALL OP_BIC_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OPP_BIC_S(2,4); +} + +static u32 FASTCALL OP_BIC_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OPP_BIC_S(3,5); +} + +static u32 FASTCALL OP_BIC_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OPP_BIC_S(2,4); +} + +static u32 FASTCALL OP_BIC_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OPP_BIC_S(3,5); +} + +static u32 FASTCALL OP_BIC_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OPP_BIC_S(2,4); +} + +//------------------MVN------------------- +#define OPP_MVN(a, b) cpu->R[REG_POS(i,12)] = ~shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OPP_MVN_S(a, b) cpu->R[REG_POS(i,12)] = ~shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a; + +static u32 FASTCALL OP_MVN_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSL_IMM; + OPP_MVN(1,3); +} + +static u32 FASTCALL OP_MVN_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OPP_MVN(2,4); +} + +static u32 FASTCALL OP_MVN_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + LSR_IMM; + OPP_MVN(1,3); +} + +static u32 FASTCALL OP_MVN_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OPP_MVN(2,4); +} + +static u32 FASTCALL OP_MVN_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ASR_IMM; + OPP_MVN(1,3); +} + +static u32 FASTCALL OP_MVN_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OPP_MVN(2,4); +} + +static u32 FASTCALL OP_MVN_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 shift_op; + ROR_IMM; + OPP_MVN(1,3); +} + +static u32 FASTCALL OP_MVN_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OPP_MVN(2,4); +} + +static u32 FASTCALL OP_MVN_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OPP_MVN(1,3); +} + +static u32 FASTCALL OP_MVN_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OPP_MVN_S(2,4); +} + +static u32 FASTCALL OP_MVN_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OPP_MVN_S(3,5); +} + +static u32 FASTCALL OP_MVN_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OPP_MVN_S(2,4); +} + +static u32 FASTCALL OP_MVN_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OPP_MVN_S(3,5); +} + +static u32 FASTCALL OP_MVN_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OPP_MVN_S(2,4); +} + +static u32 FASTCALL OP_MVN_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OPP_MVN_S(3,5); +} + +static u32 FASTCALL OP_MVN_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OPP_MVN_S(2,4); +} + +static u32 FASTCALL OP_MVN_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OPP_MVN_S(3,5); +} + +static u32 FASTCALL OP_MVN_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OPP_MVN_S(2,4); +} + +//-------------MUL------------------------ +#define OPP_M(a,b) v >>= 8;\ + if((v==0)||(v==0xFFFFFF))\ + return b;\ + v >>= 8;\ + if((v==0)||(v==0xFFFF))\ + return b+1;\ + v >>= 8;\ + if((v==0)||(v==0xFF))\ + return b+2;\ + return a;\ + +static u32 FASTCALL OP_MUL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v; + OPP_M(5,2); +} + +static u32 FASTCALL OP_MLA(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u32 a = cpu->R[REG_POS(i,8)]; + u32 b = cpu->R[REG_POS(i,12)]; + cpu->R[REG_POS(i,16)] = a * v + b; + + OPP_M(6,3); +} + +static u32 FASTCALL OP_MUL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v; + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0); + + OPP_M(6,3); +} + +static u32 FASTCALL OP_MLA_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v + cpu->R[REG_POS(i,12)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0); + OPP_M(7,4); +} + +//----------UMUL-------------------------- + +static u32 FASTCALL OP_UMULL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] = (u32)(res>>32); + + OPP_M(6,3); +} + +static u32 FASTCALL OP_UMLAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)] + (u64)cpu->R[REG_POS(i,12)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] += (u32)(res>>32); + + OPP_M(7,4); +} + +static u32 FASTCALL OP_UMULL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] = (u32)(res>>32); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0); + + OPP_M(7,4); +} + +static u32 FASTCALL OP_UMLAL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)] + (u64)cpu->R[REG_POS(i,12)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] += (u32)(res>>32); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0); + + OPP_M(8,5); +} + +//----------SMUL-------------------------- + +static u32 FASTCALL OP_SMULL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 v = (s32)cpu->R[REG_POS(i,0)]; + s64 b = (s32)cpu->R[REG_POS(i,8)]; + s64 res = v * b; + + cpu->R[REG_POS(i,12)] = (u32)(res&0xFFFFFFFF); + cpu->R[REG_POS(i,16)] = (u32)(res>>32); + + v &= 0xFFFFFFFF; + + OPP_M(6,3); +} + +static u32 FASTCALL OP_SMLAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + s64 v = (s32)cpu->R[REG_POS(i,0)]; + s64 b = (s32)cpu->R[REG_POS(i,8)]; + s64 res = v * b + (u64)cpu->R[REG_POS(i,12)]; + + //LOG("%08X * %08X + %08X%08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], cpu->R[REG_POS(i,16)], cpu->R[REG_POS(i,12)]); + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] += (u32)(res>>32); + + //LOG("= %08X%08X %08X%08X\r\n", cpu->R[REG_POS(i,16)], cpu->R[REG_POS(i,12)], res); + + v &= 0xFFFFFFFF; + + OPP_M(7,4); +} + +static u32 FASTCALL OP_SMULL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 v = (s32)cpu->R[REG_POS(i,0)]; + s64 b = (s32)cpu->R[REG_POS(i,8)]; + s64 res = v * b; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] = (u32)(res>>32); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0); + + v &= 0xFFFFFFFF; + + OPP_M(7,4); +} + +static u32 FASTCALL OP_SMLAL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 v = (s32)cpu->R[REG_POS(i,0)]; + s64 b = (s32)cpu->R[REG_POS(i,8)]; + s64 res = v * b + (u64)cpu->R[REG_POS(i,12)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] += (u32)(res>>32); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0); + + v &= 0xFFFFFFFF; + + OPP_M(8,5); +} + +//---------------SWP------------------------------ + +static u32 FASTCALL OP_SWP(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 tmp = ROR(READ32(cpu->mem_if->data, adr), ((cpu->R[REG_POS(i,16)]&3)<<3)); + + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,0)]); + cpu->R[REG_POS(i,12)] = tmp; + + return 4 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]*2; +} + +static u32 FASTCALL OP_SWPB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u8 tmp = READ8(cpu->mem_if->data, adr); + WRITE8(cpu->mem_if->data, adr, (u8)(cpu->R[REG_POS(i,0)]&0xFF)); + cpu->R[REG_POS(i,12)] = tmp; + + return 4 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]*2; +} + +//------------LDRH----------------------------- + +static u32 FASTCALL OP_LDRH_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_PRE_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] =(u32)READ16(cpu->mem_if->data, adr); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_PRE_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_POS_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] += IMM_OFF; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_POS_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] -= IMM_OFF; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_POS_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)]; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRH_POS_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)]; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//------------STRH----------------------------- + +static u32 FASTCALL OP_STRH_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,16)] = adr; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_PRE_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_PRE_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_POS_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] += IMM_OFF; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_POS_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] -= IMM_OFF; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_POS_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)]; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRH_POS_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)]; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//----------------LDRSH-------------------------- + +static u32 FASTCALL OP_LDRSH_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (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_LDRSH_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (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_LDRSH_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (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_LDRSH_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (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_LDRSH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSH_PRE_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSH_PRE_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSH_POS_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] += IMM_OFF; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSH_POS_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] -= IMM_OFF; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSH_POS_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)]; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSH_POS_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)]; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//----------------------LDRSB---------------------- + +static u32 FASTCALL OP_LDRSB_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (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_LDRSB_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (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_LDRSB_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (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_LDRSB_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (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_LDRSB_PRE_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSB_PRE_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSB_PRE_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSB_PRE_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSB_POS_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] += IMM_OFF; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSB_POS_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] -= IMM_OFF; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSB_POS_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)]; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRSB_POS_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)]; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//--------------MRS-------------------------------- + +static u32 FASTCALL OP_MRS_CPSR(armcpu_t *cpu) +{ + cpu->R[REG_POS(cpu->instruction,12)] = cpu->CPSR.val; + + return 1; +} + +static u32 FASTCALL OP_MRS_SPSR(armcpu_t *cpu) +{ + cpu->R[REG_POS(cpu->instruction,12)] = cpu->SPSR.val; + + return 1; +} + +//--------------MSR-------------------------------- + +static u32 FASTCALL OP_MSR_CPSR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 operand = cpu->R[REG_POS(i,0)]; + + if(cpu->CPSR.bits.mode!=USR) + { + if(BIT16(i)) + { + armcpu_switchMode(cpu, operand & 0x1F); + cpu->CPSR.val = (cpu->CPSR.val & 0xFFFFFF00) | (operand & 0xFF); + } + if(BIT17(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0xFFFF00FF) | (operand & 0xFF00); + if(BIT18(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0xFF00FFFF) | (operand & 0xFF0000); + } + if(BIT19(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (operand & 0xFF000000); + + return 1; +} + +static u32 FASTCALL OP_MSR_SPSR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 operand = cpu->R[REG_POS(i,0)]; + + if(cpu->CPSR.bits.mode!=USR) + { + if(BIT16(i)) + { + cpu->SPSR.val = (cpu->SPSR.val & 0xFFFFFF00) | (operand & 0XFF); + } + if(BIT17(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFFFF00FF) | (operand & 0XFF00); + if(BIT18(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFF00FFFF) | (operand & 0XFF0000); + } + if(BIT19(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0x00FFFFFF) | (operand & 0XFF000000); + + return 1; +} + +static u32 FASTCALL OP_MSR_CPSR_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + + if(cpu->CPSR.bits.mode!=USR) + { + if(BIT16(i)) + { + armcpu_switchMode(cpu, shift_op & 0x1F); + cpu->CPSR.val = (cpu->CPSR.val & 0xFFFFFF00) | (shift_op & 0XFF); + } + if(BIT17(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0xFFFF00FF) | (shift_op & 0XFF00); + if(BIT18(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0xFF00FFFF) | (shift_op & 0XFF0000); + } + if(BIT19(i)) + { + //cpu->CPSR.val = (cpu->CPSR.val & 0xFF000000) | (shift_op & 0XFF000000); + cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (shift_op & 0xFF000000); + } + + return 1; +} + +static u32 FASTCALL OP_MSR_SPSR_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + + if(cpu->CPSR.bits.mode!=USR) + { + if(BIT16(i)) + { + cpu->SPSR.val = (cpu->SPSR.val & 0xFFFFFF00) | (shift_op & 0XFF); + } + if(BIT17(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFFFF00FF) | (shift_op & 0XFF00); + if(BIT18(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFF00FFFF) | (shift_op & 0XFF0000); + } + if(BIT19(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFF000000) | (shift_op & 0XFF000000); + + return 1; +} + +//-----------------BRANCH-------------------------- + +static u32 FASTCALL OP_BX(armcpu_t *cpu) +{ + u32 tmp = cpu->R[REG_POS(cpu->instruction, 0)]; + + cpu->CPSR.bits.T = BIT0(tmp); + cpu->R[15] = tmp & 0xFFFFFFFE; + cpu->next_instruction = cpu->R[15]; + return 3; +} + +static u32 FASTCALL OP_BLX_REG(armcpu_t *cpu) +{ + u32 tmp = cpu->R[REG_POS(cpu->instruction, 0)]; + + cpu->R[14] = cpu->next_instruction; + cpu->CPSR.bits.T = BIT0(tmp); + cpu->R[15] = tmp & 0xFFFFFFFE; + cpu->next_instruction = cpu->R[15]; + return 3; +} + +#define SIGNEXTEND_24(i) (((s32)((i)<<8))>>8) + +static u32 FASTCALL OP_B(armcpu_t *cpu) +{ + u32 off = SIGNEXTEND_24(cpu->instruction); + if(CONDITION(cpu->instruction)==0xF) + { + cpu->R[14] = cpu->next_instruction; + cpu->CPSR.bits.T = 1; + } + cpu->R[15] += (off<<2); + cpu->next_instruction = cpu->R[15]; + + return 3; +} + +static u32 FASTCALL OP_BL(armcpu_t *cpu) +{ + u32 off = SIGNEXTEND_24(cpu->instruction); + if(CONDITION(cpu->instruction)==0xF) + { + cpu->CPSR.bits.T = 1; + cpu->R[15] += 2; + } + cpu->R[14] = cpu->next_instruction; + cpu->R[15] += (off<<2); + cpu->next_instruction = cpu->R[15]; + + return 3; +} + +//----------------CLZ------------------------------- + +u8 CLZ_TAB[16]= +{ + 0, // 0000 + 1, // 0001 + 2, 2, // 001X + 3, 3, 3, 3, // 01XX + 4, 4, 4, 4, 4, 4, 4, 4 // 1XXX +}; + +static u32 FASTCALL OP_CLZ(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 Rm = cpu->R[REG_POS(i,0)]; + u32 pos; + + if(Rm==0) + { + cpu->R[REG_POS(i,12)]=32; + return 2; + } + + Rm |= (Rm >>1); + Rm |= (Rm >>2); + Rm |= (Rm >>4); + Rm |= (Rm >>8); + Rm |= (Rm >>16); + + pos = + CLZ_TAB[Rm&0xF] + + CLZ_TAB[(Rm>>4)&0xF] + + CLZ_TAB[(Rm>>8)&0xF] + + CLZ_TAB[(Rm>>12)&0xF] + + CLZ_TAB[(Rm>>16)&0xF] + + CLZ_TAB[(Rm>>20)&0xF] + + CLZ_TAB[(Rm>>24)&0xF] + + CLZ_TAB[(Rm>>28)&0xF]; + + cpu->R[REG_POS(i,12)]=32 - pos; + + return 2; +} + +//--------------------QADD--QSUB------------------------------ + +static u32 FASTCALL OP_QADD(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 res = cpu->R[REG_POS(i,16)]+cpu->R[REG_POS(i,0)]; + + LOG("spe add\r\n"); + if(SIGNED_OVERFLOW(cpu->R[REG_POS(i,16)],cpu->R[REG_POS(i,0)], res)) + { + cpu->CPSR.bits.Q=1; + cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res); + return 2; + } + cpu->R[REG_POS(i,12)]=res; + if(REG_POS(i,12)==15) + { + cpu->R[15] &= 0XFFFFFFFC; + cpu->next_instruction = cpu->R[15]; + return 3; + } + return 2; +} + +static u32 FASTCALL OP_QSUB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 res = cpu->R[REG_POS(i,0)]-cpu->R[REG_POS(i,16)]; + + LOG("spe add\r\n"); + if(SIGNED_UNDERFLOW(cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,16)], res)) + { + cpu->CPSR.bits.Q=1; + cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res); + return 2; + } + cpu->R[REG_POS(i,12)]=res; + if(REG_POS(i,12)==15) + { + cpu->R[15] &= 0XFFFFFFFC; + cpu->next_instruction = cpu->R[15]; + return 3; + } + return 2; +} + +static u32 FASTCALL OP_QDADD(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 mul = cpu->R[REG_POS(i,16)]<<1; + u32 res; + + + LOG("spe add\r\n"); + if(BIT31(cpu->R[REG_POS(i,16)])!=BIT31(mul)) + { + cpu->CPSR.bits.Q=1; + mul = 0x80000000-BIT31(mul); + } + + res = mul + cpu->R[REG_POS(i,0)]; + if(SIGNED_OVERFLOW(cpu->R[REG_POS(i,0)],mul, res)) + { + cpu->CPSR.bits.Q=1; + cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res); + return 2; + } + cpu->R[REG_POS(i,12)]=res; + if(REG_POS(i,12)==15) + { + cpu->R[15] &= 0XFFFFFFFC; + cpu->next_instruction = cpu->R[15]; + return 3; + } + return 2; +} + +static u32 FASTCALL OP_QDSUB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 mul = cpu->R[REG_POS(i,16)]<<1; + u32 res; + + + LOG("spe add\r\n"); + if(BIT31(cpu->R[REG_POS(i,16)])!=BIT31(mul)) + { + cpu->CPSR.bits.Q=1; + mul = 0x80000000-BIT31(mul); + } + + res = cpu->R[REG_POS(i,0)] - mul; + if(SIGNED_UNDERFLOW(cpu->R[REG_POS(i,0)], mul, res)) + { + cpu->CPSR.bits.Q=1; + cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res); + return 2; + } + cpu->R[REG_POS(i,12)]=res; + if(REG_POS(i,12)==15) + { + cpu->R[15] &= 0XFFFFFFFC; + cpu->next_instruction = cpu->R[15]; + return 3; + } + return 2; +} + +//-----------------SMUL------------------------------- + +#define HWORD(i) ((s32)(((s32)(i))>>16)) +#define LWORD(i) (s32)(((s32)((i)<<16))>>16) + +static u32 FASTCALL OP_SMUL_B_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + cpu->R[REG_POS(i,16)] = (u32)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + + return 2; +} + +static u32 FASTCALL OP_SMUL_B_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + cpu->R[REG_POS(i,16)] = (u32)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + + return 2; +} + +static u32 FASTCALL OP_SMUL_T_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + cpu->R[REG_POS(i,16)] = (u32)(HWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + + return 2; +} + +static u32 FASTCALL OP_SMUL_T_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + cpu->R[REG_POS(i,16)] = (u32)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + + return 2; +} + +//-----------SMLA---------------------------- + +static u32 FASTCALL OP_SMLA_B_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = (u32)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLABB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +static u32 FASTCALL OP_SMLA_B_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = (u32)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLABT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +static u32 FASTCALL OP_SMLA_T_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = (u32)(HWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLATB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +static u32 FASTCALL OP_SMLA_T_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = (u32)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLATT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +//--------------SMLAL--------------------------------------- + +static u32 FASTCALL OP_SMLAL_B_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + u64 res = (u64)tmp + cpu->R[REG_POS(i,12)]; + + LOG("SMLALBB %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + (res + ((tmp<0)*0xFFFFFFFF))), (int)(u32) res); + + cpu->R[REG_POS(i,12)] = (u32) res; + cpu->R[REG_POS(i,16)] += (res + ((tmp<0)*0xFFFFFFFF)); + + return 2; +} + +static u32 FASTCALL OP_SMLAL_B_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + u64 res = (u64)tmp + cpu->R[REG_POS(i,12)]; + + LOG("SMLALBT %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res); + + cpu->R[REG_POS(i,12)] = (u32) res; + cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF); + + return 2; +} + +static u32 FASTCALL OP_SMLAL_T_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)(HWORD(cpu->R[REG_POS(i,0)])* (s64)LWORD(cpu->R[REG_POS(i,8)])); + u64 res = (u64)tmp + cpu->R[REG_POS(i,12)]; + + LOG("SMLALTB %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res); + + cpu->R[REG_POS(i,12)] = (u32) res; + cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF); + + return 2; +} + +static u32 FASTCALL OP_SMLAL_T_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + u64 res = (u64)tmp + cpu->R[REG_POS(i,12)]; + + LOG("SMLALTT %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res); + + cpu->R[REG_POS(i,12)] = (u32) res; + cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF); + + return 2; +} + +//--------------SMULW-------------------- + +static u32 FASTCALL OP_SMULW_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)LWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]); + + //LOG("SMULWB %08X * %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], ((tmp>>16)&0xFFFFFFFF); + + cpu->R[REG_POS(i,16)] = ((tmp>>16)&0xFFFFFFFF); + + return 2; +} + +static u32 FASTCALL OP_SMULW_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)HWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]); + + //LOG("SMULWT %08X * %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], ((tmp>>16)&0xFFFFFFFF)); + + cpu->R[REG_POS(i,16)] = ((tmp>>16)&0xFFFFFFFF); + + return 2; +} + +//--------------SMLAW------------------- +static u32 FASTCALL OP_SMLAW_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)LWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLAWB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, (tmp>>16) + a); + + tmp = (tmp>>16); + + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +static u32 FASTCALL OP_SMLAW_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)HWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLAWT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, ((tmp>>16)&0xFFFFFFFF) + a); + + tmp = ((tmp>>16)&0xFFFFFFFF); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +//------------LDR--------------------------- + +static u32 FASTCALL OP_LDR_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + u32 val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + u32 val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + u32 val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + u32 val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +//------------------------------------------------------------ +static u32 FASTCALL OP_LDR_P_IMM_OFF_POSTIND2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = READ32(cpu->mem_if->data, adr); + u32 old; + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + old = armcpu_switchMode(cpu, USR); + cpu->R[REG_POS(i,12)] = val; + armcpu_switchMode(cpu, old); + + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +//------------------------------------------------------------ + +static u32 FASTCALL OP_LDR_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + shift_op; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - shift_op; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr - shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + shift_op; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - shift_op; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr - shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + shift_op; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - shift_op; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr - shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + shift_op; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ32(cpu->mem_if->data, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - shift_op; + return 5 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,16)] = adr - shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +//-----------------LDRB------------------------------------------- + +static u32 FASTCALL OP_LDRB_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + u32 val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + u32 val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + u32 val = READ8(cpu->mem_if->data, adr); + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + u32 val = READ8(cpu->mem_if->data, adr); + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ8(cpu->mem_if->data, adr); + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ8(cpu->mem_if->data, adr); + + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr - shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr - shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr - shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 val; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,16)] = adr - shift_op; + cpu->R[REG_POS(i,12)] = val; + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//----------------------STR-------------------------------- + +static u32 FASTCALL OP_STR_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + +// cpu->state->execute = false; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STR_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +//-----------------------STRB------------------------------------- + +static u32 FASTCALL OP_STRB_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + WRITE8(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] + shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)] - shift_op; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr; + u32 shift_op; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//-----------------------LDRBT------------------------------------- + +static u32 FASTCALL OP_LDRBT_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + + i = cpu->instruction; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_M_IMM_OFF_POSTIND\n"); + + + i = cpu->instruction; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_P_REG_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_P_REG_OFF_POSTIND"); + + + i = cpu->instruction; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + cpu->R[REG_POS(i,0)]; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_P_LSL_IMM_OFF_POSTIND"); + + + i = cpu->instruction; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_M_LSL_IMM_OFF_POSTIND"); + + + i = cpu->instruction; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_P_LSR_IMM_OFF_POSTIND"); + + + i = cpu->instruction; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_M_LSR_IMM_OFF_POSTIND"); + + + i = cpu->instruction; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_P_ASR_IMM_OFF_POSTIND"); + + + i = cpu->instruction; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_M_ASR_IMM_OFF_POSTIND"); + + + i = cpu->instruction; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_P_ROR_IMM_OFF_POSTIND"); + + + i = cpu->instruction; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_LDRBT_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 val; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDRBT_M_ROR_IMM_OFF_POSTIND"); + + + i = cpu->instruction; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + val = READ8(cpu->mem_if->data, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//----------------------STRBT---------------------------- + +static u32 FASTCALL OP_STRBT_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_P_REG_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + cpu->R[REG_POS(i,0)]; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_M_REG_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - cpu->R[REG_POS(i,0)]; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + LSL_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + LSR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + ASR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +static u32 FASTCALL OP_STRBT_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 oldmode; + u32 i; + u32 adr; + u32 shift_op; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + oldmode = armcpu_switchMode(cpu, SYS); + + + i = cpu->instruction; + ROR_IMM; + adr = cpu->R[REG_POS(i,16)]; + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//---------------------LDM----------------------------- + +#define OP_L_IA(reg, adr) if(BIT##reg(i))\ + {\ + registres[reg] = READ32(cpu->mem_if->data, start);\ + c += waitState[(start>>24)&0xF];\ + adr += 4;\ + } + +#define OP_L_IB(reg, adr) if(BIT##reg(i))\ + {\ + adr += 4;\ + registres[reg] = READ32(cpu->mem_if->data, start);\ + c += waitState[(start>>24)&0xF];\ + } + +#define OP_L_DA(reg, adr) if(BIT##reg(i))\ + {\ + registres[reg] = READ32(cpu->mem_if->data, start);\ + c += waitState[(start>>24)&0xF];\ + adr -= 4;\ + } + +#define OP_L_DB(reg, adr) if(BIT##reg(i))\ + {\ + adr -= 4;\ + registres[reg] = READ32(cpu->mem_if->data, start);\ + c += waitState[(start>>24)&0xF];\ + } + +static u32 FASTCALL OP_LDMIA(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + OP_L_IA(0, start); + OP_L_IA(1, start); + OP_L_IA(2, start); + OP_L_IA(3, start); + OP_L_IA(4, start); + OP_L_IA(5, start); + OP_L_IA(6, start); + OP_L_IA(7, start); + OP_L_IA(8, start); + OP_L_IA(9, start); + OP_L_IA(10, start); + OP_L_IA(11, start); + OP_L_IA(12, start); + OP_L_IA(13, start); + OP_L_IA(14, start); + + if(BIT15(i)) + { + u32 tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + //start += 4; + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + + return c + 2; +} + +static u32 FASTCALL OP_LDMIB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + OP_L_IB(0, start); + OP_L_IB(1, start); + OP_L_IB(2, start); + OP_L_IB(3, start); + OP_L_IB(4, start); + OP_L_IB(5, start); + OP_L_IB(6, start); + OP_L_IB(7, start); + OP_L_IB(8, start); + OP_L_IB(9, start); + OP_L_IB(10, start); + OP_L_IB(11, start); + OP_L_IB(12, start); + OP_L_IB(13, start); + OP_L_IB(14, start); + + if(BIT15(i)) + { + u32 tmp; + start += 4; + c += waitState[(start>>24)&0xF]; + tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + cpu->next_instruction = registres[15]; + c += 2 + (c==0); + } + + return c + 2; +} + +static u32 FASTCALL OP_LDMDA(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + c += waitState[(start>>24)&0xF]; + start -= 4; + cpu->next_instruction = registres[15]; + } + + OP_L_DA(14, start); + OP_L_DA(13, start); + OP_L_DA(12, start); + OP_L_DA(11, start); + OP_L_DA(10, start); + OP_L_DA(9, start); + OP_L_DA(8, start); + OP_L_DA(7, start); + OP_L_DA(6, start); + OP_L_DA(5, start); + OP_L_DA(4, start); + OP_L_DA(3, start); + OP_L_DA(2, start); + OP_L_DA(1, start); + OP_L_DA(0, start); + + return c + 2; +} + +static u32 FASTCALL OP_LDMDB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp; + start -= 4; + tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + + OP_L_DB(14, start); + OP_L_DB(13, start); + OP_L_DB(12, start); + OP_L_DB(11, start); + OP_L_DB(10, start); + OP_L_DB(9, start); + OP_L_DB(8, start); + OP_L_DB(7, start); + OP_L_DB(6, start); + OP_L_DB(5, start); + OP_L_DB(4, start); + OP_L_DB(3, start); + OP_L_DB(2, start); + OP_L_DB(1, start); + OP_L_DB(0, start); + + return c + 2; +} + +static u32 FASTCALL OP_LDMIA_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, count; + u32 start = cpu->R[REG_POS(i,16)]; + u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF; + + u32 * registres = cpu->R; + u32 * waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + OP_L_IA(0, start); + OP_L_IA(1, start); + OP_L_IA(2, start); + OP_L_IA(3, start); + OP_L_IA(4, start); + OP_L_IA(5, start); + OP_L_IA(6, start); + OP_L_IA(7, start); + OP_L_IA(8, start); + OP_L_IA(9, start); + OP_L_IA(10, start); + OP_L_IA(11, start); + OP_L_IA(12, start); + OP_L_IA(13, start); + OP_L_IA(14, start); + + if(BIT15(i)) + { + u32 tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + c += waitState[(start>>24)&0xF]; + start += 4; + cpu->next_instruction = registres[15]; + } + + if(i & (1 << REG_POS(i,16))) { + if(i & bitList) + cpu->R[REG_POS(i,16)] = start; + } + else + cpu->R[REG_POS(i,16)] = start; + + return c + 2; +} + +static u32 FASTCALL OP_LDMIB_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, count; + u32 start = cpu->R[REG_POS(i,16)]; + u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF; + + u32 * registres = cpu->R; + u32 * waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + OP_L_IB(0, start); + OP_L_IB(1, start); + OP_L_IB(2, start); + OP_L_IB(3, start); + OP_L_IB(4, start); + OP_L_IB(5, start); + OP_L_IB(6, start); + OP_L_IB(7, start); + OP_L_IB(8, start); + OP_L_IB(9, start); + OP_L_IB(10, start); + OP_L_IB(11, start); + OP_L_IB(12, start); + OP_L_IB(13, start); + OP_L_IB(14, start); + + if(BIT15(i)) + { + u32 tmp; + start += 4; + c += waitState[(start>>24)&0xF]; + tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + cpu->next_instruction = registres[15]; + c += 2 + (c==0); + } + + if(i & (1 << REG_POS(i,16))) { + if(i & bitList) + cpu->R[REG_POS(i,16)] = start; + } + else + cpu->R[REG_POS(i,16)] = start; + + return c + 2; +} + +static u32 FASTCALL OP_LDMDA_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, count; + u32 start = cpu->R[REG_POS(i,16)]; + u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF; + + u32 * registres = cpu->R; + u32 * waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + c += waitState[(start>>24)&0xF]; + start -= 4; + cpu->next_instruction = registres[15]; + } + + OP_L_DA(14, start); + OP_L_DA(13, start); + OP_L_DA(12, start); + OP_L_DA(11, start); + OP_L_DA(10, start); + OP_L_DA(9, start); + OP_L_DA(8, start); + OP_L_DA(7, start); + OP_L_DA(6, start); + OP_L_DA(5, start); + OP_L_DA(4, start); + OP_L_DA(3, start); + OP_L_DA(2, start); + OP_L_DA(1, start); + OP_L_DA(0, start); + + if(i & (1 << REG_POS(i,16))) { + if(i & bitList) + cpu->R[REG_POS(i,16)] = start; + } + else + cpu->R[REG_POS(i,16)] = start; + + return c + 2; +} + +static u32 FASTCALL OP_LDMDB_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, count; + u32 start = cpu->R[REG_POS(i,16)]; + u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF; + u32 * registres = cpu->R; + u32 * waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp; + start -= 4; + tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + + OP_L_DB(14, start); + OP_L_DB(13, start); + OP_L_DB(12, start); + OP_L_DB(11, start); + OP_L_DB(10, start); + OP_L_DB(9, start); + OP_L_DB(8, start); + OP_L_DB(7, start); + OP_L_DB(6, start); + OP_L_DB(5, start); + OP_L_DB(4, start); + OP_L_DB(3, start); + OP_L_DB(2, start); + OP_L_DB(1, start); + OP_L_DB(0, start); + + if(i & (1 << REG_POS(i,16))) { + if(i & bitList) + cpu->R[REG_POS(i,16)] = start; + } + else + cpu->R[REG_POS(i,16)] = start; + + return c + 2; +} + +static u32 FASTCALL OP_LDMIA2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 oldmode; + + u32 c = 0; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 * registres; + u32 * waitState; + + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 1; + oldmode = armcpu_switchMode(cpu, SYS); + } + + registres = cpu->R; + waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + OP_L_IA(0, start); + OP_L_IA(1, start); + OP_L_IA(2, start); + OP_L_IA(3, start); + OP_L_IA(4, start); + OP_L_IA(5, start); + OP_L_IA(6, start); + OP_L_IA(7, start); + OP_L_IA(8, start); + OP_L_IA(9, start); + OP_L_IA(10, start); + OP_L_IA(11, start); + OP_L_IA(12, start); + OP_L_IA(13, start); + OP_L_IA(14, start); + + if(BIT15(i)) + { + u32 tmp = READ32(cpu->mem_if->data, start); + Status_Reg SPSR; + cpu->R[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + //start += 4; + cpu->next_instruction = cpu->R[15]; + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + else + { + armcpu_switchMode(cpu, oldmode); + } + return c + 2; +} + +static u32 FASTCALL OP_LDMIB2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 oldmode; + u32 c = 0; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 * registres; + u32 * waitState; + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDMIB2"); + + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + registres = cpu->R; + waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + OP_L_IB(0, start); + OP_L_IB(1, start); + OP_L_IB(2, start); + OP_L_IB(3, start); + OP_L_IB(4, start); + OP_L_IB(5, start); + OP_L_IB(6, start); + OP_L_IB(7, start); + OP_L_IB(8, start); + OP_L_IB(9, start); + OP_L_IB(10, start); + OP_L_IB(11, start); + OP_L_IB(12, start); + OP_L_IB(13, start); + OP_L_IB(14, start); + + if(BIT15(i)) + { + u32 tmp; + Status_Reg SPSR; + start += 4; + tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + else + { + armcpu_switchMode(cpu, oldmode); + } + return c + 2; +} + +static u32 FASTCALL OP_LDMDA2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + u32 oldmode; + u32 c = 0; + u32 * registres; + u32 * waitState; + + u32 start = cpu->R[REG_POS(i,16)]; + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_LDMDA2"); + + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + registres = cpu->R; + waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR = cpu->SPSR; + c += waitState[(start>>24)&0xF]; + start -= 4; + cpu->next_instruction = registres[15]; + } + + OP_L_DA(14, start); + OP_L_DA(13, start); + OP_L_DA(12, start); + OP_L_DA(11, start); + OP_L_DA(10, start); + OP_L_DA(9, start); + OP_L_DA(8, start); + OP_L_DA(7, start); + OP_L_DA(6, start); + OP_L_DA(5, start); + OP_L_DA(4, start); + OP_L_DA(3, start); + OP_L_DA(2, start); + OP_L_DA(1, start); + OP_L_DA(0, start); + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + } + else + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + } + + return c + 2; +} + +static u32 FASTCALL OP_LDMDB2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + u32 oldmode; + u32 c = 0; + u32 * registres; + u32 * waitState; + + u32 start = cpu->R[REG_POS(i,16)]; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + registres = cpu->R; + waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp; + start -= 4; + tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR = cpu->SPSR; + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + + OP_L_DB(14, start); + OP_L_DB(13, start); + OP_L_DB(12, start); + OP_L_DB(11, start); + OP_L_DB(10, start); + OP_L_DB(9, start); + OP_L_DB(8, start); + OP_L_DB(7, start); + OP_L_DB(6, start); + OP_L_DB(5, start); + OP_L_DB(4, start); + OP_L_DB(3, start); + OP_L_DB(2, start); + OP_L_DB(1, start); + OP_L_DB(0, start); + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + } + else + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + } + + return 2 + c; +} + +static u32 FASTCALL OP_LDMIA2_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + + u32 oldmode; + u32 start = cpu->R[REG_POS(i,16)]; + u32 * registres; + u32 * waitState; + u32 tmp; + Status_Reg SPSR; +// cpu->state->execute = FALSE; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + registres = cpu->R; + waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + OP_L_IA(0, start); + OP_L_IA(1, start); + OP_L_IA(2, start); + OP_L_IA(3, start); + OP_L_IA(4, start); + OP_L_IA(5, start); + OP_L_IA(6, start); + OP_L_IA(7, start); + OP_L_IA(8, start); + OP_L_IA(9, start); + OP_L_IA(10, start); + OP_L_IA(11, start); + OP_L_IA(12, start); + OP_L_IA(13, start); + OP_L_IA(14, start); + + if(BIT15(i)==0) + { + registres[REG_POS(i,16)] = start; + armcpu_switchMode(cpu, oldmode); + return c + 2; + } + + registres[REG_POS(i,16)] = start + 4; + tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + + return c + 2; +} + +static u32 FASTCALL OP_LDMIB2_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + + u32 oldmode; + u32 start = cpu->R[REG_POS(i,16)]; + u32 * registres; + u32 * waitState; + u32 tmp; + Status_Reg SPSR; + + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + registres = cpu->R; + waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + OP_L_IB(0, start); + OP_L_IB(1, start); + OP_L_IB(2, start); + OP_L_IB(3, start); + OP_L_IB(4, start); + OP_L_IB(5, start); + OP_L_IB(6, start); + OP_L_IB(7, start); + OP_L_IB(8, start); + OP_L_IB(9, start); + OP_L_IB(10, start); + OP_L_IB(11, start); + OP_L_IB(12, start); + OP_L_IB(13, start); + OP_L_IB(14, start); + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + registres[REG_POS(i,16)] = start; + + return c + 2; + } + + registres[REG_POS(i,16)] = start + 4; + tmp = READ32(cpu->mem_if->data, start + 4); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR = cpu->SPSR; + cpu->next_instruction = registres[15]; + SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + c += waitState[(start>>24)&0xF]; + + return c + 2; +} + +static u32 FASTCALL OP_LDMDA2_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + + u32 oldmode; + u32 start = cpu->R[REG_POS(i,16)]; + u32 * registres; + u32 * waitState; + Status_Reg SPSR; +// cpu->state->execute = FALSE; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + registres = cpu->R; + waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp = READ32(cpu->mem_if->data, start); + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + c += waitState[(start>>24)&0xF]; + start -= 4; + cpu->next_instruction = registres[15]; + } + + OP_L_DA(14, start); + OP_L_DA(13, start); + OP_L_DA(12, start); + OP_L_DA(11, start); + OP_L_DA(10, start); + OP_L_DA(9, start); + OP_L_DA(8, start); + OP_L_DA(7, start); + OP_L_DA(6, start); + OP_L_DA(5, start); + OP_L_DA(4, start); + OP_L_DA(3, start); + OP_L_DA(2, start); + OP_L_DA(1, start); + OP_L_DA(0, start); + + registres[REG_POS(i,16)] = start; + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + return c + 2; + } + + SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + return c + 2; +} + +static u32 FASTCALL OP_LDMDB2_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + + u32 oldmode; + u32 start = cpu->R[REG_POS(i,16)]; + u32 * registres; + u32 * waitState; + Status_Reg SPSR; +// cpu->state->execute = FALSE; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + registres = cpu->R; + waitState = cpu->state->MMU->MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp; + start -= 4; + tmp = READ32(cpu->mem_if->data, start); + c += waitState[(start>>24)&0xF]; + registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR = cpu->SPSR; + cpu->next_instruction = registres[15]; + } + + OP_L_DB(14, start); + OP_L_DB(13, start); + OP_L_DB(12, start); + OP_L_DB(11, start); + OP_L_DB(10, start); + OP_L_DB(9, start); + OP_L_DB(8, start); + OP_L_DB(7, start); + OP_L_DB(6, start); + OP_L_DB(5, start); + OP_L_DB(4, start); + OP_L_DB(3, start); + OP_L_DB(2, start); + OP_L_DB(1, start); + OP_L_DB(0, start); + + registres[REG_POS(i,16)] = start; + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + return c + 2; + } + + SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + return c + 2; +} + +//------------------------------STM---------------------------------- + +static u32 FASTCALL OP_STMIA(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + WRITE32(cpu->mem_if->data, start, cpu->R[b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start += 4; + } + } + return c + 1; +} + +static u32 FASTCALL OP_STMIB(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + start += 4; + WRITE32(cpu->mem_if->data, start, cpu->R[b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + return c + 1; +} + +static u32 FASTCALL OP_STMDA(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + WRITE32(cpu->mem_if->data, start, cpu->R[15-b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start -= 4; + } + } + return c + 1; +} + +static u32 FASTCALL OP_STMDB(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + start -= 4; + WRITE32(cpu->mem_if->data, start, cpu->R[15-b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + return c + 1; +} + +static u32 FASTCALL OP_STMIA_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + WRITE32(cpu->mem_if->data, start, cpu->R[b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start += 4; + } + } + + cpu->R[REG_POS(i,16)] = start; + return c + 1; +} + +static u32 FASTCALL OP_STMIB_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + start += 4; + WRITE32(cpu->mem_if->data, start, cpu->R[b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + cpu->R[REG_POS(i,16)] = start; + return c + 1; +} + +static u32 FASTCALL OP_STMDA_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + WRITE32(cpu->mem_if->data, start, cpu->R[15-b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start -= 4; + } + } + + cpu->R[REG_POS(i,16)] = start; + return c + 1; +} + +static u32 FASTCALL OP_STMDB_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction, c = 0, b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + start -= 4; + WRITE32(cpu->mem_if->data, start, cpu->R[15-b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + + cpu->R[REG_POS(i,16)] = start; + return c + 1; +} + +static u32 FASTCALL OP_STMIA2(armcpu_t *cpu) +{ + u32 i, c, b; + u32 start; + u32 oldmode; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + i = cpu->instruction; + c = 0; + start = cpu->R[REG_POS(i,16)]; + oldmode = armcpu_switchMode(cpu, SYS); + + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_STMIA2"); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + WRITE32(cpu->mem_if->data, start, cpu->R[b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start += 4; + } + } + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +static u32 FASTCALL OP_STMIB2(armcpu_t *cpu) +{ + u32 i, c, b; + u32 start; + u32 oldmode; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + i = cpu->instruction; + c = 0; + start = cpu->R[REG_POS(i,16)]; + oldmode = armcpu_switchMode(cpu, SYS); + + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_STMIB2"); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + start += 4; + WRITE32(cpu->mem_if->data, start, cpu->R[b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +static u32 FASTCALL OP_STMDA2(armcpu_t *cpu) +{ + u32 i, c, b; + u32 start; + u32 oldmode; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + i = cpu->instruction; + c = 0; + start = cpu->R[REG_POS(i,16)]; + oldmode = armcpu_switchMode(cpu, SYS); + + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_STMDA2"); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + WRITE32(cpu->mem_if->data, start, cpu->R[15-b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start -= 4; + } + } + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +static u32 FASTCALL OP_STMDB2(armcpu_t *cpu) +{ + u32 i, c, b; + u32 start; + u32 oldmode; + + if(cpu->CPSR.bits.mode==USR) + return 2; + i = cpu->instruction; + c=0; + start = cpu->R[REG_POS(i,16)]; + oldmode = armcpu_switchMode(cpu, SYS); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + start -= 4; + WRITE32(cpu->mem_if->data, start, cpu->R[15-b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +static u32 FASTCALL OP_STMIA2_W(armcpu_t *cpu) +{ + u32 i, c, b; + u32 start; + u32 oldmode; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + i = cpu->instruction; + c=0; + start = cpu->R[REG_POS(i,16)]; + oldmode = armcpu_switchMode(cpu, SYS); + + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_STMIA2_W"); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + WRITE32(cpu->mem_if->data, start, cpu->R[b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start += 4; + } + } + + cpu->R[REG_POS(i,16)] = start; + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +static u32 FASTCALL OP_STMIB2_W(armcpu_t *cpu) +{ + u32 i, c, b; + u32 start; + u32 oldmode; + + if(cpu->CPSR.bits.mode==USR) + return 2; + i = cpu->instruction; + c=0; + start = cpu->R[REG_POS(i,16)]; + oldmode = armcpu_switchMode(cpu, SYS); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + start += 4; + WRITE32(cpu->mem_if->data, start, cpu->R[b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + armcpu_switchMode(cpu, oldmode); + cpu->R[REG_POS(i,16)] = start; + + return c + 1; +} + +static u32 FASTCALL OP_STMDA2_W(armcpu_t *cpu) +{ + u32 i, c, b; + u32 start; + u32 oldmode; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + i = cpu->instruction; + c = 0; + start = cpu->R[REG_POS(i,16)]; + oldmode = armcpu_switchMode(cpu, SYS); + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_STMDA2_W"); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + WRITE32(cpu->mem_if->data, start, cpu->R[15-b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start -= 4; + } + } + + cpu->R[REG_POS(i,16)] = start; + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +static u32 FASTCALL OP_STMDB2_W(armcpu_t *cpu) +{ + u32 i, c, b; + u32 start; + u32 oldmode; + + if(cpu->CPSR.bits.mode==USR) + return 2; + + i = cpu->instruction; + c = 0; + + start = cpu->R[REG_POS(i,16)]; + oldmode = armcpu_switchMode(cpu, SYS); + + //cpu->state->execute = FALSE; + LOG("Untested opcode: OP_STMDB2_W"); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + start -= 4; + WRITE32(cpu->mem_if->data, start, cpu->R[15-b]); + c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + + cpu->R[REG_POS(i,16)] = start; + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +/* + * + * The Enhanced DSP Extension LDRD and STRD instructions. + * + */ +static u32 FASTCALL +OP_LDRD_STRD_POST_INDEX( armcpu_t *cpu) { + u32 i = cpu->instruction; + u32 Rd_num = REG_POS( i, 12); + u32 addr = cpu->R[REG_POS(i,16)]; + u32 index; + + /* I bit - immediate or register */ + if ( BIT22(i)) + index = IMM_OFF; + else + index = cpu->R[REG_POS(i,0)]; + + /* U bit - add or subtract */ + if ( BIT23(i)) + cpu->R[REG_POS(i,16)] += index; + else + cpu->R[REG_POS(i,16)] -= index; + + if ( !(Rd_num & 0x1)) { + /* Store/Load */ + if ( BIT5(i)) { + WRITE32(cpu->mem_if->data, addr, cpu->R[Rd_num]); + WRITE32(cpu->mem_if->data, addr + 4, cpu->R[Rd_num + 1]); + } + else { + cpu->R[Rd_num] = READ32(cpu->mem_if->data, addr); + cpu->R[Rd_num + 1] = READ32(cpu->mem_if->data, addr + 4); + } + } + + return 3 + (cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(addr>>24)&0xF] * 2); +} + +static u32 FASTCALL +OP_LDRD_STRD_OFFSET_PRE_INDEX( armcpu_t *cpu) { + u32 i = cpu->instruction; + u32 Rd_num = REG_POS( i, 12); + u32 addr = cpu->R[REG_POS(i,16)]; + u32 index; + + /* I bit - immediate or register */ + if ( BIT22(i)) + index = IMM_OFF; + else + index = cpu->R[REG_POS(i,0)]; + + /* U bit - add or subtract */ + if ( BIT23(i)) { + addr += index; + + /* W bit - writeback */ + if ( BIT21(i)) + cpu->R[REG_POS(i,16)] = addr; + } + else { + addr -= index; + + /* W bit - writeback */ + if ( BIT21(i)) + cpu->R[REG_POS(i,16)] = addr; + } + + if ( !(Rd_num & 0x1)) { + /* Store/Load */ + if ( BIT5(i)) { + WRITE32(cpu->mem_if->data, addr, cpu->R[Rd_num]); + WRITE32(cpu->mem_if->data, addr + 4, cpu->R[Rd_num + 1]); + } + else { + cpu->R[Rd_num] = READ32(cpu->mem_if->data, addr); + cpu->R[Rd_num + 1] = READ32(cpu->mem_if->data, addr + 4); + } + } + + return 3 + (cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(addr>>24)&0xF] * 2); +} + + + +//---------------------STC---------------------------------- + +static u32 FASTCALL OP_STC_P_IMM_OFF(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_STC_M_IMM_OFF(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_STC_P_PREIND(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_STC_M_PREIND(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_STC_P_POSTIND(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_STC_M_POSTIND(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_STC_OPTION(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */ + return 2; + } +} + +//---------------------LDC---------------------------------- + +static u32 FASTCALL OP_LDC_P_IMM_OFF(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_LDC_M_IMM_OFF(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_LDC_P_PREIND(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_LDC_M_PREIND(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_LDC_P_POSTIND(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_LDC_M_POSTIND(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */ + return 2; + } +} + +static u32 FASTCALL OP_LDC_OPTION(armcpu_t *cpu) +{ + { + /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */ + return 2; + } +} + +//----------------MCR----------------------- + +static u32 FASTCALL OP_MCR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 cpnum = REG_POS(i, 8); + + if(!cpu->coproc[cpnum]) + { + cpu->state->execute = FALSE; + return 2; + } + + armcp15_moveARM2CP((armcp15_t*)cpu->coproc[cpnum], cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7); + //cpu->coproc[cpnum]->moveARM2CP(cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7); + return 2; +} + +//----------------MRC----------------------- + +static u32 FASTCALL OP_MRC(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 cpnum = REG_POS(i, 8); + + if(!cpu->coproc[cpnum]) + { + cpu->state->execute = FALSE; + return 2; + } + + armcp15_moveCP2ARM((armcp15_t*)cpu->coproc[cpnum], &cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7); + //cpu->coproc[cpnum]->moveCP2ARM(&cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7); + return 4; +} + +//--------------SWI------------------------------- +static u32 FASTCALL OP_SWI(armcpu_t *cpu) +{ + if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9))) + { + /* TODO (#1#): translocated SWI vectors */ + /* 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 4; + } + else + { + u32 swinum = (cpu->instruction>>16)&0x1F; + return cpu->swi_tab[swinum](cpu) + 3; + } +} + +//----------------BKPT------------------------- +static u32 FASTCALL OP_BKPT(armcpu_t *cpu) +{ + cpu->state->execute = FALSE; + return 4; +} + +//----------------CDP----------------------- + +static u32 FASTCALL OP_CDP(armcpu_t *cpu) +{ + cpu->state->execute = FALSE; + return 4; +} + +#define TYPE_RETOUR u32 +#define PARAMETRES armcpu_t *cpu +#define CALLTYPE FASTCALL +#define NOM_TAB arm_instructions_set + +#include "instruction_tabdef.inc" diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/arm_instructions.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/arm_instructions.h new file mode 100755 index 000000000..350680aaf --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/arm_instructions.h @@ -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 + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/armcpu.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/armcpu.c new file mode 100755 index 000000000..48351dc72 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/armcpu.c @@ -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 +#include + +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; +} + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/armcpu.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/armcpu.h new file mode 100755 index 000000000..b7d8c4df3 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/armcpu.h @@ -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<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<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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bios.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bios.c new file mode 100755 index 000000000..80b506c29 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bios.c @@ -0,0 +1,1080 @@ +/* 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 "cp15.h" +#include +#include "MMU.h" +#include "spu_exports.h" +#include "debug.h" + +#include "state.h" + +static const u16 getsinetbl[] = { +0x0000, 0x0324, 0x0648, 0x096A, 0x0C8C, 0x0FAB, 0x12C8, 0x15E2, +0x18F9, 0x1C0B, 0x1F1A, 0x2223, 0x2528, 0x2826, 0x2B1F, 0x2E11, +0x30FB, 0x33DF, 0x36BA, 0x398C, 0x3C56, 0x3F17, 0x41CE, 0x447A, +0x471C, 0x49B4, 0x4C3F, 0x4EBF, 0x5133, 0x539B, 0x55F5, 0x5842, +0x5A82, 0x5CB3, 0x5ED7, 0x60EB, 0x62F1, 0x64E8, 0x66CF, 0x68A6, +0x6A6D, 0x6C23, 0x6DC9, 0x6F5E, 0x70E2, 0x7254, 0x73B5, 0x7504, +0x7641, 0x776B, 0x7884, 0x7989, 0x7A7C, 0x7B5C, 0x7C29, 0x7CE3, +0x7D89, 0x7E1D, 0x7E9C, 0x7F09, 0x7F61, 0x7FA6, 0x7FD8, 0x7FF5 +}; + +static const u16 getpitchtbl[] = { +0x0000, 0x003B, 0x0076, 0x00B2, 0x00ED, 0x0128, 0x0164, 0x019F, +0x01DB, 0x0217, 0x0252, 0x028E, 0x02CA, 0x0305, 0x0341, 0x037D, +0x03B9, 0x03F5, 0x0431, 0x046E, 0x04AA, 0x04E6, 0x0522, 0x055F, +0x059B, 0x05D8, 0x0614, 0x0651, 0x068D, 0x06CA, 0x0707, 0x0743, +0x0780, 0x07BD, 0x07FA, 0x0837, 0x0874, 0x08B1, 0x08EF, 0x092C, +0x0969, 0x09A7, 0x09E4, 0x0A21, 0x0A5F, 0x0A9C, 0x0ADA, 0x0B18, +0x0B56, 0x0B93, 0x0BD1, 0x0C0F, 0x0C4D, 0x0C8B, 0x0CC9, 0x0D07, +0x0D45, 0x0D84, 0x0DC2, 0x0E00, 0x0E3F, 0x0E7D, 0x0EBC, 0x0EFA, +0x0F39, 0x0F78, 0x0FB6, 0x0FF5, 0x1034, 0x1073, 0x10B2, 0x10F1, +0x1130, 0x116F, 0x11AE, 0x11EE, 0x122D, 0x126C, 0x12AC, 0x12EB, +0x132B, 0x136B, 0x13AA, 0x13EA, 0x142A, 0x146A, 0x14A9, 0x14E9, +0x1529, 0x1569, 0x15AA, 0x15EA, 0x162A, 0x166A, 0x16AB, 0x16EB, +0x172C, 0x176C, 0x17AD, 0x17ED, 0x182E, 0x186F, 0x18B0, 0x18F0, +0x1931, 0x1972, 0x19B3, 0x19F5, 0x1A36, 0x1A77, 0x1AB8, 0x1AFA, +0x1B3B, 0x1B7D, 0x1BBE, 0x1C00, 0x1C41, 0x1C83, 0x1CC5, 0x1D07, +0x1D48, 0x1D8A, 0x1DCC, 0x1E0E, 0x1E51, 0x1E93, 0x1ED5, 0x1F17, +0x1F5A, 0x1F9C, 0x1FDF, 0x2021, 0x2064, 0x20A6, 0x20E9, 0x212C, +0x216F, 0x21B2, 0x21F5, 0x2238, 0x227B, 0x22BE, 0x2301, 0x2344, +0x2388, 0x23CB, 0x240E, 0x2452, 0x2496, 0x24D9, 0x251D, 0x2561, +0x25A4, 0x25E8, 0x262C, 0x2670, 0x26B4, 0x26F8, 0x273D, 0x2781, +0x27C5, 0x280A, 0x284E, 0x2892, 0x28D7, 0x291C, 0x2960, 0x29A5, +0x29EA, 0x2A2F, 0x2A74, 0x2AB9, 0x2AFE, 0x2B43, 0x2B88, 0x2BCD, +0x2C13, 0x2C58, 0x2C9D, 0x2CE3, 0x2D28, 0x2D6E, 0x2DB4, 0x2DF9, +0x2E3F, 0x2E85, 0x2ECB, 0x2F11, 0x2F57, 0x2F9D, 0x2FE3, 0x302A, +0x3070, 0x30B6, 0x30FD, 0x3143, 0x318A, 0x31D0, 0x3217, 0x325E, +0x32A5, 0x32EC, 0x3332, 0x3379, 0x33C1, 0x3408, 0x344F, 0x3496, +0x34DD, 0x3525, 0x356C, 0x35B4, 0x35FB, 0x3643, 0x368B, 0x36D3, +0x371A, 0x3762, 0x37AA, 0x37F2, 0x383A, 0x3883, 0x38CB, 0x3913, +0x395C, 0x39A4, 0x39ED, 0x3A35, 0x3A7E, 0x3AC6, 0x3B0F, 0x3B58, +0x3BA1, 0x3BEA, 0x3C33, 0x3C7C, 0x3CC5, 0x3D0E, 0x3D58, 0x3DA1, +0x3DEA, 0x3E34, 0x3E7D, 0x3EC7, 0x3F11, 0x3F5A, 0x3FA4, 0x3FEE, +0x4038, 0x4082, 0x40CC, 0x4116, 0x4161, 0x41AB, 0x41F5, 0x4240, +0x428A, 0x42D5, 0x431F, 0x436A, 0x43B5, 0x4400, 0x444B, 0x4495, +0x44E1, 0x452C, 0x4577, 0x45C2, 0x460D, 0x4659, 0x46A4, 0x46F0, +0x473B, 0x4787, 0x47D3, 0x481E, 0x486A, 0x48B6, 0x4902, 0x494E, +0x499A, 0x49E6, 0x4A33, 0x4A7F, 0x4ACB, 0x4B18, 0x4B64, 0x4BB1, +0x4BFE, 0x4C4A, 0x4C97, 0x4CE4, 0x4D31, 0x4D7E, 0x4DCB, 0x4E18, +0x4E66, 0x4EB3, 0x4F00, 0x4F4E, 0x4F9B, 0x4FE9, 0x5036, 0x5084, +0x50D2, 0x5120, 0x516E, 0x51BC, 0x520A, 0x5258, 0x52A6, 0x52F4, +0x5343, 0x5391, 0x53E0, 0x542E, 0x547D, 0x54CC, 0x551A, 0x5569, +0x55B8, 0x5607, 0x5656, 0x56A5, 0x56F4, 0x5744, 0x5793, 0x57E2, +0x5832, 0x5882, 0x58D1, 0x5921, 0x5971, 0x59C1, 0x5A10, 0x5A60, +0x5AB0, 0x5B01, 0x5B51, 0x5BA1, 0x5BF1, 0x5C42, 0x5C92, 0x5CE3, +0x5D34, 0x5D84, 0x5DD5, 0x5E26, 0x5E77, 0x5EC8, 0x5F19, 0x5F6A, +0x5FBB, 0x600D, 0x605E, 0x60B0, 0x6101, 0x6153, 0x61A4, 0x61F6, +0x6248, 0x629A, 0x62EC, 0x633E, 0x6390, 0x63E2, 0x6434, 0x6487, +0x64D9, 0x652C, 0x657E, 0x65D1, 0x6624, 0x6676, 0x66C9, 0x671C, +0x676F, 0x67C2, 0x6815, 0x6869, 0x68BC, 0x690F, 0x6963, 0x69B6, +0x6A0A, 0x6A5E, 0x6AB1, 0x6B05, 0x6B59, 0x6BAD, 0x6C01, 0x6C55, +0x6CAA, 0x6CFE, 0x6D52, 0x6DA7, 0x6DFB, 0x6E50, 0x6EA4, 0x6EF9, +0x6F4E, 0x6FA3, 0x6FF8, 0x704D, 0x70A2, 0x70F7, 0x714D, 0x71A2, +0x71F7, 0x724D, 0x72A2, 0x72F8, 0x734E, 0x73A4, 0x73FA, 0x7450, +0x74A6, 0x74FC, 0x7552, 0x75A8, 0x75FF, 0x7655, 0x76AC, 0x7702, +0x7759, 0x77B0, 0x7807, 0x785E, 0x78B4, 0x790C, 0x7963, 0x79BA, +0x7A11, 0x7A69, 0x7AC0, 0x7B18, 0x7B6F, 0x7BC7, 0x7C1F, 0x7C77, +0x7CCF, 0x7D27, 0x7D7F, 0x7DD7, 0x7E2F, 0x7E88, 0x7EE0, 0x7F38, +0x7F91, 0x7FEA, 0x8042, 0x809B, 0x80F4, 0x814D, 0x81A6, 0x81FF, +0x8259, 0x82B2, 0x830B, 0x8365, 0x83BE, 0x8418, 0x8472, 0x84CB, +0x8525, 0x857F, 0x85D9, 0x8633, 0x868E, 0x86E8, 0x8742, 0x879D, +0x87F7, 0x8852, 0x88AC, 0x8907, 0x8962, 0x89BD, 0x8A18, 0x8A73, +0x8ACE, 0x8B2A, 0x8B85, 0x8BE0, 0x8C3C, 0x8C97, 0x8CF3, 0x8D4F, +0x8DAB, 0x8E07, 0x8E63, 0x8EBF, 0x8F1B, 0x8F77, 0x8FD4, 0x9030, +0x908C, 0x90E9, 0x9146, 0x91A2, 0x91FF, 0x925C, 0x92B9, 0x9316, +0x9373, 0x93D1, 0x942E, 0x948C, 0x94E9, 0x9547, 0x95A4, 0x9602, +0x9660, 0x96BE, 0x971C, 0x977A, 0x97D8, 0x9836, 0x9895, 0x98F3, +0x9952, 0x99B0, 0x9A0F, 0x9A6E, 0x9ACD, 0x9B2C, 0x9B8B, 0x9BEA, +0x9C49, 0x9CA8, 0x9D08, 0x9D67, 0x9DC7, 0x9E26, 0x9E86, 0x9EE6, +0x9F46, 0x9FA6, 0xA006, 0xA066, 0xA0C6, 0xA127, 0xA187, 0xA1E8, +0xA248, 0xA2A9, 0xA30A, 0xA36B, 0xA3CC, 0xA42D, 0xA48E, 0xA4EF, +0xA550, 0xA5B2, 0xA613, 0xA675, 0xA6D6, 0xA738, 0xA79A, 0xA7FC, +0xA85E, 0xA8C0, 0xA922, 0xA984, 0xA9E7, 0xAA49, 0xAAAC, 0xAB0E, +0xAB71, 0xABD4, 0xAC37, 0xAC9A, 0xACFD, 0xAD60, 0xADC3, 0xAE27, +0xAE8A, 0xAEED, 0xAF51, 0xAFB5, 0xB019, 0xB07C, 0xB0E0, 0xB145, +0xB1A9, 0xB20D, 0xB271, 0xB2D6, 0xB33A, 0xB39F, 0xB403, 0xB468, +0xB4CD, 0xB532, 0xB597, 0xB5FC, 0xB662, 0xB6C7, 0xB72C, 0xB792, +0xB7F7, 0xB85D, 0xB8C3, 0xB929, 0xB98F, 0xB9F5, 0xBA5B, 0xBAC1, +0xBB28, 0xBB8E, 0xBBF5, 0xBC5B, 0xBCC2, 0xBD29, 0xBD90, 0xBDF7, +0xBE5E, 0xBEC5, 0xBF2C, 0xBF94, 0xBFFB, 0xC063, 0xC0CA, 0xC132, +0xC19A, 0xC202, 0xC26A, 0xC2D2, 0xC33A, 0xC3A2, 0xC40B, 0xC473, +0xC4DC, 0xC544, 0xC5AD, 0xC616, 0xC67F, 0xC6E8, 0xC751, 0xC7BB, +0xC824, 0xC88D, 0xC8F7, 0xC960, 0xC9CA, 0xCA34, 0xCA9E, 0xCB08, +0xCB72, 0xCBDC, 0xCC47, 0xCCB1, 0xCD1B, 0xCD86, 0xCDF1, 0xCE5B, +0xCEC6, 0xCF31, 0xCF9C, 0xD008, 0xD073, 0xD0DE, 0xD14A, 0xD1B5, +0xD221, 0xD28D, 0xD2F8, 0xD364, 0xD3D0, 0xD43D, 0xD4A9, 0xD515, +0xD582, 0xD5EE, 0xD65B, 0xD6C7, 0xD734, 0xD7A1, 0xD80E, 0xD87B, +0xD8E9, 0xD956, 0xD9C3, 0xDA31, 0xDA9E, 0xDB0C, 0xDB7A, 0xDBE8, +0xDC56, 0xDCC4, 0xDD32, 0xDDA0, 0xDE0F, 0xDE7D, 0xDEEC, 0xDF5B, +0xDFC9, 0xE038, 0xE0A7, 0xE116, 0xE186, 0xE1F5, 0xE264, 0xE2D4, +0xE343, 0xE3B3, 0xE423, 0xE493, 0xE503, 0xE573, 0xE5E3, 0xE654, +0xE6C4, 0xE735, 0xE7A5, 0xE816, 0xE887, 0xE8F8, 0xE969, 0xE9DA, +0xEA4B, 0xEABC, 0xEB2E, 0xEB9F, 0xEC11, 0xEC83, 0xECF5, 0xED66, +0xEDD9, 0xEE4B, 0xEEBD, 0xEF2F, 0xEFA2, 0xF014, 0xF087, 0xF0FA, +0xF16D, 0xF1E0, 0xF253, 0xF2C6, 0xF339, 0xF3AD, 0xF420, 0xF494, +0xF507, 0xF57B, 0xF5EF, 0xF663, 0xF6D7, 0xF74C, 0xF7C0, 0xF834, +0xF8A9, 0xF91E, 0xF992, 0xFA07, 0xFA7C, 0xFAF1, 0xFB66, 0xFBDC, +0xFC51, 0xFCC7, 0xFD3C, 0xFDB2, 0xFE28, 0xFE9E, 0xFF14, 0xFF8A +}; + +static const u8 getvoltbl[] = { +0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, +0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, +0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, +0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, +0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, +0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, +0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, +0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C, +0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, +0x22, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x29, +0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x31, 0x31, +0x32, 0x32, 0x33, 0x33, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x38, 0x38, 0x39, 0x3A, 0x3A, 0x3B, +0x3C, 0x3C, 0x3D, 0x3E, 0x3F, 0x3F, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x45, 0x45, 0x46, 0x47, +0x48, 0x49, 0x4A, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x52, 0x53, 0x54, 0x55, +0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67, +0x68, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6F, 0x71, 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A, 0x7B, +0x7D, 0x7E, 0x7F, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, +0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, +0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x30, 0x31, 0x31, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x36, +0x36, 0x37, 0x37, 0x38, 0x39, 0x39, 0x3A, 0x3B, 0x3B, 0x3C, 0x3D, 0x3E, 0x3E, 0x3F, 0x40, 0x40, +0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4D, +0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, +0x5E, 0x5F, 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6F, 0x70, +0x71, 0x73, 0x74, 0x75, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7E, 0x7E, 0x40, 0x41, 0x42, 0x43, 0x43, +0x44, 0x45, 0x46, 0x47, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, +0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, +0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x70, 0x71, 0x72, 0x74, 0x75, +0x76, 0x78, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, +0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, +0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x65, 0x66, +0x67, 0x68, 0x69, 0x6A, 0x6C, 0x6D, 0x6E, 0x6F, 0x71, 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A, +0x7C, 0x7D, 0x7E, 0x7F +}; + +u32 bios_nop(armcpu_t * cpu) +{ + if (cpu->proc_ID == ARMCPU_ARM9) + { + LOG("Unimplemented bios function %02X(ARM9) was used. R0:%08X\n", (cpu->instruction)&0x1F, cpu->R[0]); + } + else + { + LOG("Unimplemented bios function %02X(ARM7) was used. R0:%08X\n", (cpu->instruction)&0x1F, cpu->R[0]); + } + return 3; +} + +u32 delayLoop(armcpu_t * cpu) +{ + return cpu->R[0] * 4; +} + +//u32 oldmode[2]; + +u32 intrWaitARM(armcpu_t * cpu) +{ + u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; + u32 intr; + u32 intrFlag = 0; + + //cpu->state->execute = FALSE; + if(cpu->proc_ID) + { + intrFlagAdr = 0x380FFF8; + } else { + intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; + } + intr = MMU_read32(cpu->state, cpu->proc_ID, intrFlagAdr); + intrFlag = cpu->R[1] & intr; + + if(intrFlag) + { + // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s) + // on efface son(les) occurence(s). + intr ^= intrFlag; + MMU_write32(cpu->state, cpu->proc_ID, intrFlagAdr, intr); + //cpu->switchMode(oldmode[cpu->proc_ID]); + return 1; + } + + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + cpu->waitIRQ = 1; + //oldmode[cpu->proc_ID] = cpu->switchMode(SVC); + + return 1; +} + +u32 waitVBlankARM(armcpu_t * cpu) +{ + u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; + u32 intr; + u32 intrFlag = 0; + + //cpu->state->execute = FALSE; + if(cpu->proc_ID) + { + intrFlagAdr = 0x380FFF8; + } else { + intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; + } + intr = MMU_read32(cpu->state, cpu->proc_ID, intrFlagAdr); + intrFlag = 1 & intr; + + if(intrFlag) + { + // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s) + // on efface son(les) occurence(s). + intr ^= intrFlag; + MMU_write32(cpu->state, cpu->proc_ID, intrFlagAdr, intr); + //cpu->switchMode(oldmode[cpu->proc_ID]); + return 1; + } + + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + cpu->waitIRQ = 1; + //oldmode[cpu->proc_ID] = cpu->switchMode(SVC); + + return 1; +} + +u32 wait4IRQ(armcpu_t* cpu) +{ + //cpu->state->execute= FALSE; + if(cpu->wirq) + { + if(!cpu->waitIRQ) + { + cpu->waitIRQ = 0; + cpu->wirq = 0; + //cpu->switchMode(oldmode[cpu->proc_ID]); + return 1; + } + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + return 1; + } + cpu->waitIRQ = 1; + cpu->wirq = 1; + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + //oldmode[cpu->proc_ID] = cpu->switchMode(SVC); + return 1; +} + +u32 devide(armcpu_t* cpu) +{ + s32 num = (s32)cpu->R[0]; + s32 dnum = (s32)cpu->R[1]; + + if(dnum==0) return 0; + + cpu->R[0] = (u32)(num / dnum); + cpu->R[1] = (u32)(num % dnum); + cpu->R[3] = (u32) (((s32)cpu->R[0])<0 ? -cpu->R[0] : cpu->R[0]); + + return 6; +} + +u32 copy(armcpu_t* cpu) +{ + u32 src = cpu->R[0]; + u32 dst = cpu->R[1]; + u32 cnt = cpu->R[2]; + + switch(BIT26(cnt)) + { + case 0: + src &= 0xFFFFFFFE; + dst &= 0xFFFFFFFE; + switch(BIT24(cnt)) + { + case 0: + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_write16(cpu->state, cpu->proc_ID, dst, MMU_read16(cpu->state, cpu->proc_ID, src)); + cnt--; + dst+=2; + src+=2; + } + break; + case 1: + { + u32 val = MMU_read16(cpu->state, cpu->proc_ID, src); + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_write16(cpu->state, cpu->proc_ID, dst, val); + cnt--; + dst+=2; + } + } + break; + } + break; + case 1: + src &= 0xFFFFFFFC; + dst &= 0xFFFFFFFC; + switch(BIT24(cnt)) + { + case 0: + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_write32(cpu->state, cpu->proc_ID, dst, MMU_read32(cpu->state, cpu->proc_ID, src)); + cnt--; + dst+=4; + src+=4; + } + break; + case 1: + { + u32 val = MMU_read32(cpu->state, cpu->proc_ID, src); + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_write32(cpu->state, cpu->proc_ID, dst, val); + cnt--; + dst+=4; + } + } + break; + } + break; + } + return 1; +} + +u32 fastCopy(armcpu_t* cpu) +{ + u32 src = cpu->R[0] & 0xFFFFFFFC; + u32 dst = cpu->R[1] & 0xFFFFFFFC; + u32 cnt = cpu->R[2]; + + switch(BIT24(cnt)) + { + case 0: + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_write32(cpu->state, cpu->proc_ID, dst, MMU_read32(cpu->state, cpu->proc_ID, src)); + cnt--; + dst+=4; + src+=4; + } + break; + case 1: + { + u32 val = MMU_read32(cpu->state, cpu->proc_ID, src); + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_write32(cpu->state, cpu->proc_ID, dst, val); + cnt--; + dst+=4; + } + } + break; + } + return 1; +} + +u32 LZ77UnCompVram(armcpu_t* cpu) +{ + int i1, i2; + int byteCount; + int byteShift; + u32 writeValue; + int len; + u32 source = cpu->R[0]; + u32 dest = cpu->R[1]; + u32 header = MMU_read32(cpu->state, cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + byteCount = 0; + byteShift = 0; + writeValue = 0; + + len = header >> 8; + + while(len > 0) { + u8 d = MMU_read8(cpu->state, cpu->proc_ID, source++); + + if(d) { + for(i1 = 0; i1 < 8; i1++) { + if(d & 0x80) { + int length; + int offset; + u32 windowOffset; + u16 data = MMU_read8(cpu->state, cpu->proc_ID, source++) << 8; + data |= MMU_read8(cpu->state, cpu->proc_ID, source++); + length = (data >> 12) + 3; + offset = (data & 0x0FFF); + windowOffset = dest + byteCount - offset - 1; + for(i2 = 0; i2 < length; i2++) { + writeValue |= (MMU_read8(cpu->state, cpu->proc_ID, windowOffset++) << byteShift); + byteShift += 8; + byteCount++; + + if(byteCount == 2) { + MMU_write16(cpu->state, cpu->proc_ID, dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + } else { + writeValue |= (MMU_read8(cpu->state, cpu->proc_ID, source++) << byteShift); + byteShift += 8; + byteCount++; + if(byteCount == 2) { + MMU_write16(cpu->state, cpu->proc_ID, dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + d <<= 1; + } + } else { + for(i1 = 0; i1 < 8; i1++) { + writeValue |= (MMU_read8(cpu->state, cpu->proc_ID, source++) << byteShift); + byteShift += 8; + byteCount++; + if(byteCount == 2) { + MMU_write16(cpu->state, cpu->proc_ID, dest, writeValue); + dest += 2; + byteShift = 0; + byteCount = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + } + } + return 1; +} + +u32 LZ77UnCompWram(armcpu_t* cpu) +{ + int i1, i2; + int len; + u32 source = cpu->R[0]; + u32 dest = cpu->R[1]; + + u32 header = MMU_read32(cpu->state, cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + len = header >> 8; + + while(len > 0) { + u8 d = MMU_read8(cpu->state, cpu->proc_ID, source++); + + if(d) { + for(i1 = 0; i1 < 8; i1++) { + if(d & 0x80) { + int length; + int offset; + u32 windowOffset; + u16 data = MMU_read8(cpu->state, cpu->proc_ID, source++) << 8; + data |= MMU_read8(cpu->state, cpu->proc_ID, source++); + length = (data >> 12) + 3; + offset = (data & 0x0FFF); + windowOffset = dest - offset - 1; + for(i2 = 0; i2 < length; i2++) { + MMU_write8(cpu->state, cpu->proc_ID, dest++, MMU_read8(cpu->state, cpu->proc_ID, windowOffset++)); + len--; + if(len == 0) + return 0; + } + } else { + MMU_write8(cpu->state, cpu->proc_ID, dest++, MMU_read8(cpu->state, cpu->proc_ID, source++)); + len--; + if(len == 0) + return 0; + } + d <<= 1; + } + } else { + for(i1 = 0; i1 < 8; i1++) { + MMU_write8(cpu->state, cpu->proc_ID, dest++, MMU_read8(cpu->state, cpu->proc_ID, source++)); + len--; + if(len == 0) + return 0; + } + } + } + return 1; +} + +u32 RLUnCompVram(armcpu_t* cpu) +{ + int i; + int len; + int byteCount; + int byteShift; + u32 writeValue; + u32 source = cpu->R[0]; + u32 dest = cpu->R[1]; + + u32 header = MMU_read32(cpu->state, cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + len = header >> 8; + byteCount = 0; + byteShift = 0; + writeValue = 0; + + while(len > 0) { + u8 d = MMU_read8(cpu->state, cpu->proc_ID, source++); + int l = d & 0x7F; + if(d & 0x80) { + u8 data = MMU_read8(cpu->state, cpu->proc_ID, source++); + l += 3; + for(i = 0;i < l; i++) { + writeValue |= (data << byteShift); + byteShift += 8; + byteCount++; + + if(byteCount == 2) { + MMU_write16(cpu->state, cpu->proc_ID, dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + } else { + l++; + for(i = 0; i < l; i++) { + writeValue |= (MMU_read8(cpu->state, cpu->proc_ID, source++) << byteShift); + byteShift += 8; + byteCount++; + if(byteCount == 2) { + MMU_write16(cpu->state, cpu->proc_ID, dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + } + } + return 1; +} + +u32 RLUnCompWram(armcpu_t* cpu) +{ + int i; + int len; + u32 source = cpu->R[0]; + u32 dest = cpu->R[1]; + + u32 header = MMU_read32(cpu->state, cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + len = header >> 8; + + while(len > 0) { + u8 d = MMU_read8(cpu->state, cpu->proc_ID, source++); + int l = d & 0x7F; + if(d & 0x80) { + u8 data = MMU_read8(cpu->state, cpu->proc_ID, source++); + l += 3; + for(i = 0;i < l; i++) { + MMU_write8(cpu->state, cpu->proc_ID, dest++, data); + len--; + if(len == 0) + return 0; + } + } else { + l++; + for(i = 0; i < l; i++) { + MMU_write8(cpu->state, cpu->proc_ID, dest++, MMU_read8(cpu->state, cpu->proc_ID, source++)); + len--; + if(len == 0) + return 0; + } + } + } + return 1; +} + +u32 UnCompHuffman(armcpu_t* cpu) +{ + u32 source, dest, writeValue, header, treeStart, mask; + u32 data; + u8 treeSize, currentNode, rootNode; + int byteCount, byteShift, len, pos; + int writeData; + + source = cpu->R[0]; + dest = cpu->R[1]; + + header = MMU_read8(cpu->state, cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + treeSize = MMU_read8(cpu->state, cpu->proc_ID, source++); + + treeStart = source; + + source += ((treeSize+1)<<1)-1; // minus because we already skipped one byte + + len = header >> 8; + + mask = 0x80000000; + data = MMU_read8(cpu->state, cpu->proc_ID, source); + source += 4; + + pos = 0; + rootNode = MMU_read8(cpu->state, cpu->proc_ID, treeStart); + currentNode = rootNode; + writeData = 0; + byteShift = 0; + byteCount = 0; + writeValue = 0; + + if((header & 0x0F) == 8) { + while(len > 0) { + // take left + if(pos == 0) + pos++; + else + pos += (((currentNode & 0x3F)+1)<<1); + + if(data & mask) { + // right + if(currentNode & 0x40) + writeData = 1; + currentNode = MMU_read8(cpu->state, cpu->proc_ID, treeStart+pos+1); + } else { + // left + if(currentNode & 0x80) + writeData = 1; + currentNode = MMU_read8(cpu->state, cpu->proc_ID, treeStart+pos); + } + + if(writeData) { + writeValue |= (currentNode << byteShift); + byteCount++; + byteShift += 8; + + pos = 0; + currentNode = rootNode; + writeData = 0; + + if(byteCount == 4) { + byteCount = 0; + byteShift = 0; + MMU_write8(cpu->state, cpu->proc_ID, dest, writeValue); + writeValue = 0; + dest += 4; + len -= 4; + } + } + mask >>= 1; + if(mask == 0) { + mask = 0x80000000; + data = MMU_read8(cpu->state, cpu->proc_ID, source); + source += 4; + } + } + } else { + int halfLen = 0; + int value = 0; + while(len > 0) { + // take left + if(pos == 0) + pos++; + else + pos += (((currentNode & 0x3F)+1)<<1); + + if((data & mask)) { + // right + if(currentNode & 0x40) + writeData = 1; + currentNode = MMU_read8(cpu->state, cpu->proc_ID, treeStart+pos+1); + } else { + // left + if(currentNode & 0x80) + writeData = 1; + currentNode = MMU_read8(cpu->state, cpu->proc_ID, treeStart+pos); + } + + if(writeData) { + if(halfLen == 0) + value |= currentNode; + else + value |= (currentNode<<4); + + halfLen += 4; + if(halfLen == 8) { + writeValue |= (value << byteShift); + byteCount++; + byteShift += 8; + + halfLen = 0; + value = 0; + + if(byteCount == 4) { + byteCount = 0; + byteShift = 0; + MMU_write8(cpu->state, cpu->proc_ID, dest, writeValue); + dest += 4; + writeValue = 0; + len -= 4; + } + } + pos = 0; + currentNode = rootNode; + writeData = 0; + } + mask >>= 1; + if(mask == 0) { + mask = 0x80000000; + data = MMU_read8(cpu->state, cpu->proc_ID, source); + source += 4; + } + } + } + return 1; +} + +u32 BitUnPack(armcpu_t* cpu) +{ + u32 source,dest,header,base,d,temp; + int len,bits,revbits,dataSize,data,bitwritecount,mask,bitcount,addBase; + u8 b; + + source = cpu->R[0]; + dest = cpu->R[1]; + header = cpu->R[2]; + + len = MMU_read16(cpu->state, cpu->proc_ID, header); + // check address + bits = MMU_read8(cpu->state, cpu->proc_ID, header+2); + revbits = 8 - bits; + // u32 value = 0; + base = MMU_read8(cpu->state, cpu->proc_ID, header+4); + addBase = (base & 0x80000000) ? 1 : 0; + base &= 0x7fffffff; + dataSize = MMU_read8(cpu->state, cpu->proc_ID, header+3); + + data = 0; + bitwritecount = 0; + while(1) { + len -= 1; + if(len < 0) + break; + mask = 0xff >> revbits; + b = MMU_read8(cpu->state, cpu->proc_ID, source); + source++; + bitcount = 0; + while(1) { + if(bitcount >= 8) + break; + d = b & mask; + temp = d >> bitcount; + if(!temp && addBase) { + temp += base; + } + data |= temp << bitwritecount; + bitwritecount += dataSize; + if(bitwritecount >= 32) { + MMU_write8(cpu->state, cpu->proc_ID, dest, data); + dest += 4; + data = 0; + bitwritecount = 0; + } + mask <<= bits; + bitcount += bits; + } + } + return 1; +} + +u32 Diff8bitUnFilterWram(armcpu_t* cpu) +{ + u32 source,dest,header; + u8 data,diff; + int len; + + source = cpu->R[0]; + dest = cpu->R[1]; + + header = MMU_read8(cpu->state, cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + (( (source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)) + return 0; + + len = header >> 8; + + data = MMU_read8(cpu->state, cpu->proc_ID, source++); + MMU_write8(cpu->state, cpu->proc_ID, dest++, data); + len--; + + while(len > 0) { + diff = MMU_read8(cpu->state, cpu->proc_ID, source++); + data += diff; + MMU_write8(cpu->state, cpu->proc_ID, dest++, data); + len--; + } + return 1; +} + +u32 Diff16bitUnFilter(armcpu_t* cpu) +{ + u32 source,dest,header; + u16 data; + int len; + + source = cpu->R[0]; + dest = cpu->R[1]; + + header = MMU_read8(cpu->state, cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + len = header >> 8; + + data = MMU_read16(cpu->state, cpu->proc_ID, source); + source += 2; + MMU_write16(cpu->state, cpu->proc_ID, dest, data); + dest += 2; + len -= 2; + + while(len >= 2) { + u16 diff = MMU_read16(cpu->state, cpu->proc_ID, source); + source += 2; + data += diff; + MMU_write16(cpu->state, cpu->proc_ID, dest, data); + dest += 2; + len -= 2; + } + return 1; +} + +u32 bios_sqrt(armcpu_t* cpu) +{ + cpu->R[0] = (u32)sqrt((double)(cpu->R[0])); + return 1; +} + +u32 setHaltCR(armcpu_t* cpu) +{ + MMU_write8(cpu->state, cpu->proc_ID, 0x4000300+cpu->proc_ID, cpu->R[0]); + return 1; +} + +u32 getSineTab(armcpu_t* cpu) +{ + cpu->R[0] = getsinetbl[cpu->R[0]]; + return 1; +} + +u32 getPitchTab(armcpu_t* cpu) +{ + cpu->R[0] = getpitchtbl[cpu->R[0]]; + return 1; +} + +u32 getVolumeTab(armcpu_t* cpu) +{ + cpu->R[0] = getvoltbl[cpu->R[0]]; + return 1; +} + +u32 getCRC16(armcpu_t* cpu) +{ + unsigned int i,j; + + u32 crc = cpu->R[0]; + u32 datap = cpu->R[1]; + u32 size = cpu->R[2]; + + static u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 }; + for(i = 0; i < size; i++) + { + crc = crc ^ MMU_read8( cpu->state, cpu->proc_ID, datap + 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)); + } + } + } + cpu->R[0] = crc; + return 1; +} + +u32 SoundBias(armcpu_t* cpu) +{ + // u32 current = SPU_ReadLong(0x4000504); + // if (cpu->R[0] > current) + //SPU_WriteLong(0x4000504, current + 0x1); + // else + //SPU_WriteLong(0x4000504, current - 0x1); + // return cpu->R[1]; + + u32 curBias = MMU_read32(cpu->state, ARMCPU_ARM7,0x04000504); + u32 newBias = (curBias == 0) ? 0x000:0x200; + u32 delay = (newBias > curBias) ? (newBias-curBias) : (curBias-newBias); + + MMU_write32(cpu->state, ARMCPU_ARM7,0x04000504, newBias); + return cpu->R[1] * delay; +} + +u32 (* ARM9_swi_tab[32])(armcpu_t* cpu)={ + bios_nop, // 0x00 + bios_nop, // 0x01 + bios_nop, // 0x02 + delayLoop, // 0x03 + intrWaitARM, // 0x04 + waitVBlankARM, // 0x05 + wait4IRQ, // 0x06 + bios_nop, // 0x07 + bios_nop, // 0x08 + devide, // 0x09 + bios_nop, // 0x0A + copy, // 0x0B + fastCopy, // 0x0C + bios_sqrt, // 0x0D + getCRC16, // 0x0E + bios_nop, // 0x0F + BitUnPack, // 0x10 + LZ77UnCompWram, // 0x11 + LZ77UnCompVram, // 0x12 + UnCompHuffman, // 0x13 + RLUnCompWram, // 0x14 + RLUnCompVram, // 0x15 + Diff8bitUnFilterWram, // 0x16 + bios_nop, // 0x17 + Diff16bitUnFilter, // 0x18 + bios_nop, // 0x19 + bios_nop, // 0x1A + bios_nop, // 0x1B + bios_nop, // 0x1C + bios_nop, // 0x1D + bios_nop, // 0x1E + setHaltCR, // 0x1F +}; + +u32 (* ARM7_swi_tab[32])(armcpu_t* cpu)={ + bios_nop, // 0x00 + bios_nop, // 0x01 + bios_nop, // 0x02 + delayLoop, // 0x03 + intrWaitARM, // 0x04 + waitVBlankARM, // 0x05 + wait4IRQ, // 0x06 + wait4IRQ, // 0x07 + SoundBias, // 0x08 + devide, // 0x09 + bios_nop, // 0x0A + copy, // 0x0B + fastCopy, // 0x0C + bios_sqrt, // 0x0D + getCRC16, // 0x0E + bios_nop, // 0x0F + BitUnPack, // 0x10 + LZ77UnCompWram, // 0x11 + LZ77UnCompVram, // 0x12 + UnCompHuffman, // 0x13 + RLUnCompWram, // 0x14 + RLUnCompVram, // 0x15 + Diff8bitUnFilterWram, // 0x16 + bios_nop, // 0x17 + bios_nop, // 0x18 + bios_nop, // 0x19 + getSineTab, // 0x1A + getPitchTab, // 0x1B + getVolumeTab, // 0x1C + bios_nop, // 0x1D + bios_nop, // 0x1E + setHaltCR, // 0x1F +}; diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bios.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bios.h new file mode 100755 index 000000000..7f717cb8c --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bios.h @@ -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 + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bits.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bits.h new file mode 100755 index 000000000..be64f65d7 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/bits.h @@ -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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/config.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/config.h new file mode 100755 index 000000000..2f2f707ee --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/config.h @@ -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 + +#include "debug.h" + +#endif /*__CONFIG_H__*/ + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/cp15.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/cp15.c new file mode 100755 index 000000000..db688c879 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/cp15.c @@ -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 + +#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; + } +} + + + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/cp15.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/cp15.h new file mode 100755 index 000000000..49496f3e5 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/cp15.h @@ -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__*/ diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/debug.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/debug.h new file mode 100755 index 000000000..8725029f5 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/debug.h @@ -0,0 +1,11 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#define LOG(...) +#define GPULOG(...) +#define DIVLOG(...) +#define SQRTLOG(...) +#define CARDLOG(...) +#define DMALOG(...) + +#endif diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/dscard.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/dscard.h new file mode 100755 index 000000000..9b002e347 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/dscard.h @@ -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__*/ + + + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/instruction_tabdef.inc b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/instruction_tabdef.inc new file mode 100755 index 000000000..f63763a73 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/instruction_tabdef.inc @@ -0,0 +1,4400 @@ +/* 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 +*/ + +TYPE_RETOUR (*CALLTYPE NOM_TAB[4096])(PARAMETRES)={ + OP_AND_LSL_IMM, // 000 0000 0 0000 + OP_AND_LSL_REG, // 000 0000 0 0001 + OP_AND_LSR_IMM, // 000 0000 0 0010 + OP_AND_LSR_REG, // 000 0000 0 0011 + OP_AND_ASR_IMM, // 000 0000 0 0100 + OP_AND_ASR_REG, // 000 0000 0 0101 + OP_AND_ROR_IMM, // 000 0000 0 0110 + OP_AND_ROR_REG, // 000 0000 0 0111 + + OP_AND_LSL_IMM, // 000 0000 0 1000 + OP_MUL, // 000 0000 0 1001 + OP_AND_LSR_IMM, // OOO OOOO O 1010 + OP_STRH_POS_INDE_M_REG_OFF, // 000 0000 0 1011 + OP_AND_ASR_IMM, // 000 0000 0 1100 + OP_LDRD_STRD_POST_INDEX, + // 000 0000 0 1101 + OP_AND_ROR_IMM, // 000 0000 0 1110 + OP_LDRD_STRD_POST_INDEX, + // 000 0000 0 1111 + + OP_AND_S_LSL_IMM, // 000 0000 1 0000 + OP_AND_S_LSL_REG, // 000 0000 1 0001 + OP_AND_S_LSR_IMM, // 000 0000 1 0010 + OP_AND_S_LSR_REG, // 000 0000 1 0011 + OP_AND_S_ASR_IMM, // 000 0000 1 0100 + OP_AND_S_ASR_REG, // 000 0000 1 0101 + OP_AND_S_ROR_IMM, // 000 0000 1 0110 + OP_AND_S_ROR_REG, // 000 0000 1 0111 + + OP_AND_S_LSL_IMM, // 000 0000 1 1000 + OP_MUL_S, // 000 0000 1 1001 + OP_AND_S_LSR_IMM, // 000 0000 1 1010 + OP_LDRH_POS_INDE_M_REG_OFF, // 000 0000 1 1011 + OP_AND_S_ASR_IMM, // 000 0000 1 1100 + OP_LDRSB_POS_INDE_M_REG_OFF,// 000 0000 1 1101 + OP_AND_S_ROR_IMM, // 000 0000 1 1110 + OP_LDRSH_POS_INDE_M_REG_OFF,// 000 0000 1 1111 + + OP_EOR_LSL_IMM, // 000 0001 0 0000 + OP_EOR_LSL_REG, // 000 0001 0 0001 + OP_EOR_LSR_IMM, // 000 0001 0 0010 + OP_EOR_LSR_REG, // 000 0001 0 0011 + OP_EOR_ASR_IMM, // 000 0001 0 0100 + OP_EOR_ASR_REG, // 000 0001 0 0101 + OP_EOR_ROR_IMM, // 000 0001 0 0110 + OP_EOR_ROR_REG, // 000 0001 0 0111 + + OP_EOR_LSL_IMM, // 000 0001 0 1000 + OP_MLA, // 000 0001 0 1001 + OP_EOR_LSR_IMM, // OOO OOO1 O 1010 + OP_UND, // 000 0001 0 1011 + OP_EOR_ASR_IMM, // 000 0001 0 1100 + OP_UND, // 000 0001 0 1101 + OP_EOR_ROR_IMM, // 000 0001 0 1110 + OP_UND, // 000 0001 0 1111 + + OP_EOR_S_LSL_IMM, // 000 0001 1 0000 + OP_EOR_S_LSL_REG, // 000 0001 1 0001 + OP_EOR_S_LSR_IMM, // 000 0001 1 0010 + OP_EOR_S_LSR_REG, // 000 0001 1 0011 + OP_EOR_S_ASR_IMM, // 000 0001 1 0100 + OP_EOR_S_ASR_REG, // 000 0001 1 0101 + OP_EOR_S_ROR_IMM, // 000 0001 1 0110 + OP_EOR_S_ROR_REG, // 000 0001 1 0111 + + OP_EOR_S_LSL_IMM, // 000 0001 1 1000 + OP_MLA_S, // 000 0001 1 1001 + OP_EOR_S_LSR_IMM, // 000 0001 1 1010 + OP_UND, // 000 0001 1 1011 + OP_EOR_S_ASR_IMM, // 000 0001 1 1100 + OP_UND, // 000 0001 1 1101 + OP_EOR_S_ROR_IMM, // 000 0001 1 1110 + OP_UND, // 000 0001 1 1111 + + OP_SUB_LSL_IMM, // 000 0010 0 0000 + OP_SUB_LSL_REG, // 000 0010 0 0001 + OP_SUB_LSR_IMM, // 000 0010 0 0010 + OP_SUB_LSR_REG, // 000 0010 0 0011 + OP_SUB_ASR_IMM, // 000 0010 0 0100 + OP_SUB_ASR_REG, // 000 0010 0 0101 + OP_SUB_ROR_IMM, // 000 0010 0 0110 + OP_SUB_ROR_REG, // 000 0010 0 0111 + + OP_SUB_LSL_IMM, // 000 0010 0 1000 + OP_UND, // 000 0010 0 1001 + OP_SUB_LSR_IMM, // OOO OO1O O 1010 + OP_STRH_POS_INDE_M_IMM_OFF, // 000 0010 0 1011 + OP_SUB_ASR_IMM, // 000 0010 0 1100 + OP_LDRD_STRD_POST_INDEX, + // 000 0010 0 1101 + OP_SUB_ROR_IMM, // 000 0010 0 1110 + OP_LDRD_STRD_POST_INDEX, + // 000 0010 0 1111 + + OP_SUB_S_LSL_IMM, // 000 0010 1 0000 + OP_SUB_S_LSL_REG, // 000 0010 1 0001 + OP_SUB_S_LSR_IMM, // 000 0010 1 0010 + OP_SUB_S_LSR_REG, // 000 0010 1 0011 + OP_SUB_S_ASR_IMM, // 000 0010 1 0100 + OP_SUB_S_ASR_REG, // 000 0010 1 0101 + OP_SUB_S_ROR_IMM, // 000 0010 1 0110 + OP_SUB_S_ROR_REG, // 000 0010 1 0111 + + OP_SUB_S_LSL_IMM, // 000 0010 1 1000 + OP_UND, // 000 0010 1 1001 + OP_SUB_S_LSR_IMM, // 000 0010 1 1010 + OP_LDRH_POS_INDE_M_IMM_OFF, // 000 0010 1 1011 + OP_SUB_S_ASR_IMM, // 000 0010 1 1100 + OP_LDRSB_POS_INDE_M_IMM_OFF,// 000 0010 1 1101 + OP_SUB_S_ROR_IMM, // 000 0010 1 1110 + OP_LDRSH_POS_INDE_M_IMM_OFF,// 000 0010 1 1111 +//-------------------- + OP_RSB_LSL_IMM, // 000 0011 0 0000 + OP_RSB_LSL_REG, // 000 0011 0 0001 + OP_RSB_LSR_IMM, // 000 0011 0 0010 + OP_RSB_LSR_REG, // 000 0011 0 0011 + OP_RSB_ASR_IMM, // 000 0011 0 0100 + OP_RSB_ASR_REG, // 000 0011 0 0101 + OP_RSB_ROR_IMM, // 000 0011 0 0110 + OP_RSB_ROR_REG, // 000 0011 0 0111 + + OP_RSB_LSL_IMM, // 000 0011 0 1000 + OP_UND, // 000 0011 0 1001 + OP_RSB_LSR_IMM, // OOO OO11 O 1010 + OP_UND, // 000 0011 0 1011 + OP_RSB_ASR_IMM, // 000 0011 0 1100 + OP_UND, // 000 0011 0 1101 + OP_RSB_ROR_IMM, // 000 0011 0 1110 + OP_UND, // 000 0011 0 1111 + + OP_RSB_S_LSL_IMM, // 000 0011 1 0000 + OP_RSB_S_LSL_REG, // 000 0011 1 0001 + OP_RSB_S_LSR_IMM, // 000 0011 1 0010 + OP_RSB_S_LSR_REG, // 000 0011 1 0011 + OP_RSB_S_ASR_IMM, // 000 0011 1 0100 + OP_RSB_S_ASR_REG, // 000 0011 1 0101 + OP_RSB_S_ROR_IMM, // 000 0011 1 0110 + OP_RSB_S_ROR_REG, // 000 0011 1 0111 + + OP_RSB_S_LSL_IMM, // 000 0011 1 1000 + OP_UND, // 000 0011 1 1001 + OP_RSB_S_LSR_IMM, // 000 0011 1 1010 + OP_UND, // 000 0011 1 1011 + OP_RSB_S_ASR_IMM, // 000 0011 1 1100 + OP_UND, // 000 0011 1 1101 + OP_RSB_S_ROR_IMM, // 000 0011 1 1110 + OP_UND, // 000 0011 1 1111 +//-------------------------- + OP_ADD_LSL_IMM, // 000 0100 0 0000 + OP_ADD_LSL_REG, // 000 0100 0 0001 + OP_ADD_LSR_IMM, // 000 0100 0 0010 + OP_ADD_LSR_REG, // 000 0100 0 0011 + OP_ADD_ASR_IMM, // 000 0100 0 0100 + OP_ADD_ASR_REG, // 000 0100 0 0101 + OP_ADD_ROR_IMM, // 000 0100 0 0110 + OP_ADD_ROR_REG, // 000 0100 0 0111 + + OP_ADD_LSL_IMM, // 000 0100 0 1000 + OP_UMULL, // 000 0100 0 1001 + OP_ADD_LSR_IMM, // OOO O10O O 1010 + OP_STRH_POS_INDE_P_REG_OFF, // 000 0100 0 1011 + OP_ADD_ASR_IMM, // 000 0100 0 1100 + OP_LDRD_STRD_POST_INDEX, + // 000 0100 0 1101 + OP_ADD_ROR_IMM, // 000 0100 0 1110 + OP_LDRD_STRD_POST_INDEX, + // 000 0100 0 1111 + + OP_ADD_S_LSL_IMM, // 000 0100 1 0000 + OP_ADD_S_LSL_REG, // 000 0100 1 0001 + OP_ADD_S_LSR_IMM, // 000 0100 1 0010 + OP_ADD_S_LSR_REG, // 000 0100 1 0011 + OP_ADD_S_ASR_IMM, // 000 0100 1 0100 + OP_ADD_S_ASR_REG, // 000 0100 1 0101 + OP_ADD_S_ROR_IMM, // 000 0100 1 0110 + OP_ADD_S_ROR_REG, // 000 0100 1 0111 + + OP_ADD_S_LSL_IMM, // 000 0100 1 1000 + OP_UMULL_S, // 000 0100 1 1001 + OP_ADD_S_LSR_IMM, // 000 0100 1 1010 + OP_LDRH_POS_INDE_P_REG_OFF, // 000 0100 1 1011 + OP_ADD_S_ASR_IMM, // 000 0100 1 1100 + OP_LDRSB_POS_INDE_P_REG_OFF,// 000 0100 1 1101 + OP_ADD_S_ROR_IMM, // 000 0100 1 1110 + OP_LDRSH_POS_INDE_P_REG_OFF,// 000 0100 1 1111 +//----------------------------------------- + OP_ADC_LSL_IMM, // 000 0101 0 0000 + OP_ADC_LSL_REG, // 000 0101 0 0001 + OP_ADC_LSR_IMM, // 000 0101 0 0010 + OP_ADC_LSR_REG, // 000 0101 0 0011 + OP_ADC_ASR_IMM, // 000 0101 0 0100 + OP_ADC_ASR_REG, // 000 0101 0 0101 + OP_ADC_ROR_IMM, // 000 0101 0 0110 + OP_ADC_ROR_REG, // 000 0101 0 0111 + + OP_ADC_LSL_IMM, // 000 0101 0 1000 + OP_UMLAL, // 000 0101 0 1001 + OP_ADC_LSR_IMM, // OOO O101 O 1010 + OP_UND, // 000 0101 0 1011 + OP_ADC_ASR_IMM, // 000 0101 0 1100 + OP_UND, // 000 0101 0 1101 + OP_ADC_ROR_IMM, // 000 0101 0 1110 + OP_UND, // 000 0101 0 1111 + + OP_ADC_S_LSL_IMM, // 000 0101 1 0000 + OP_ADC_S_LSL_REG, // 000 0101 1 0001 + OP_ADC_S_LSR_IMM, // 000 0101 1 0010 + OP_ADC_S_LSR_REG, // 000 0101 1 0011 + OP_ADC_S_ASR_IMM, // 000 0101 1 0100 + OP_ADC_S_ASR_REG, // 000 0101 1 0101 + OP_ADC_S_ROR_IMM, // 000 0101 1 0110 + OP_ADC_S_ROR_REG, // 000 0101 1 0111 + + OP_ADC_S_LSL_IMM, // 000 0101 1 1000 + OP_UMLAL_S, // 000 0101 1 1001 + OP_ADC_S_LSR_IMM, // 000 0101 1 1010 + OP_UND, // 000 0101 1 1011 + OP_ADC_S_ASR_IMM, // 000 0101 1 1100 + OP_UND, // 000 0101 1 1101 + OP_ADC_S_ROR_IMM, // 000 0101 1 1110 + OP_UND, // 000 0101 1 1111 +//------------------------------------------ + OP_SBC_LSL_IMM, // 000 0110 0 0000 + OP_SBC_LSL_REG, // 000 0110 0 0001 + OP_SBC_LSR_IMM, // 000 0110 0 0010 + OP_SBC_LSR_REG, // 000 0110 0 0011 + OP_SBC_ASR_IMM, // 000 0110 0 0100 + OP_SBC_ASR_REG, // 000 0110 0 0101 + OP_SBC_ROR_IMM, // 000 0110 0 0110 + OP_SBC_ROR_REG, // 000 0110 0 0111 + + OP_SBC_LSL_IMM, // 000 0110 0 1000 + OP_SMULL, // 000 0110 0 1001 + OP_SBC_LSR_IMM, // OOO O11O O 1010 + OP_STRH_POS_INDE_P_IMM_OFF, // 000 0110 0 1011 + OP_SBC_ASR_IMM, // 000 0110 0 1100 + OP_LDRD_STRD_POST_INDEX, + // 000 0110 0 1101 + OP_SBC_ROR_IMM, // 000 0110 0 1110 + OP_LDRD_STRD_POST_INDEX, + // 000 0110 0 1111 + + OP_SBC_S_LSL_IMM, // 000 0110 1 0000 + OP_SBC_S_LSL_REG, // 000 0110 1 0001 + OP_SBC_S_LSR_IMM, // 000 0110 1 0010 + OP_SBC_S_LSR_REG, // 000 0110 1 0011 + OP_SBC_S_ASR_IMM, // 000 0110 1 0100 + OP_SBC_S_ASR_REG, // 000 0110 1 0101 + OP_SBC_S_ROR_IMM, // 000 0110 1 0110 + OP_SBC_S_ROR_REG, // 000 0110 1 0111 + + OP_SBC_S_LSL_IMM, // 000 0110 1 1000 + OP_SMULL_S, // 000 0110 1 1001 + OP_SBC_S_LSR_IMM, // 000 0110 1 1010 + OP_LDRH_POS_INDE_P_IMM_OFF, // 000 0110 1 1011 + OP_SBC_S_ASR_IMM, // 000 0110 1 1100 + OP_LDRSB_POS_INDE_P_IMM_OFF,// 000 0110 1 1101 + OP_SBC_S_ROR_IMM, // 000 0110 1 1110 + OP_LDRSH_POS_INDE_P_IMM_OFF,// 000 0110 1 1111 +//------------------------------------------ + OP_RSC_LSL_IMM, // 000 0111 0 0000 + OP_RSC_LSL_REG, // 000 0111 0 0001 + OP_RSC_LSR_IMM, // 000 0111 0 0010 + OP_RSC_LSR_REG, // 000 0111 0 0011 + OP_RSC_ASR_IMM, // 000 0111 0 0100 + OP_RSC_ASR_REG, // 000 0111 0 0101 + OP_RSC_ROR_IMM, // 000 0111 0 0110 + OP_RSC_ROR_REG, // 000 0111 0 0111 + + OP_RSC_LSL_IMM, // 000 0111 0 1000 + OP_SMLAL, // 000 0111 0 1001 + OP_RSC_LSR_IMM, // OOO O111 O 1010 + OP_UND, // 000 0111 0 1011 + OP_RSC_ASR_IMM, // 000 0111 0 1100 + OP_UND, // 000 0111 0 1101 + OP_RSC_ROR_IMM, // 000 0111 0 1110 + OP_UND, // 000 0111 0 1111 + + OP_RSC_S_LSL_IMM, // 000 0111 1 0000 + OP_RSC_S_LSL_REG, // 000 0111 1 0001 + OP_RSC_S_LSR_IMM, // 000 0111 1 0010 + OP_RSC_S_LSR_REG, // 000 0111 1 0011 + OP_RSC_S_ASR_IMM, // 000 0111 1 0100 + OP_RSC_S_ASR_REG, // 000 0111 1 0101 + OP_RSC_S_ROR_IMM, // 000 0111 1 0110 + OP_RSC_S_ROR_REG, // 000 0111 1 0111 + + OP_RSC_S_LSL_IMM, // 000 0111 1 1000 + OP_SMLAL_S, // 000 0111 1 1001 + OP_RSC_S_LSR_IMM, // 000 0111 1 1010 + OP_UND, // 000 0111 1 1011 + OP_RSC_S_ASR_IMM, // 000 0111 1 1100 + OP_UND, // 000 0111 1 1101 + OP_RSC_S_ROR_IMM, // 000 0111 1 1110 + OP_UND, // 000 0111 1 1111 +//------------------------------------------ + OP_MRS_CPSR, // 000 1000 0 0000 + OP_UND, // 000 1000 0 0001 + OP_UND, // 000 1000 0 0010 + OP_UND, // 000 1000 0 0011 + OP_UND, // 000 1000 0 0100 + OP_QADD, // 000 1000 0 0101 + OP_UND, // 000 1000 0 0110 + OP_UND, // 000 1000 0 0111 + + OP_SMLA_B_B, // 000 1000 0 1000 + OP_SWP, // 000 1000 0 1001 + OP_SMLA_T_B, // 000 1000 0 1010 + OP_STRH_M_REG_OFF, // 000 1000 0 1011 + OP_SMLA_B_T, // 000 1000 0 1100 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1000 0 1101 + OP_SMLA_T_T, // 000 1000 0 1110 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1000 0 1111 + + OP_TST_LSL_IMM, // 000 1000 1 0000 + OP_TST_LSL_REG, // 000 1000 1 0001 + OP_TST_LSR_IMM, // 000 1000 1 0010 + OP_TST_LSR_REG, // 000 1000 1 0011 + OP_TST_ASR_IMM, // 000 1000 1 0100 + OP_TST_ASR_REG, // 000 1000 1 0101 + OP_TST_ROR_IMM, // 000 1000 1 0110 + OP_TST_ROR_REG, // 000 1000 1 0111 + + OP_TST_LSL_IMM, // 000 1000 1 1000 + OP_UND, // 000 1000 1 1001 + OP_TST_LSR_IMM, // OOO 100O 1 1010 + OP_LDRH_M_REG_OFF, // 000 1000 1 1011 + OP_TST_ASR_IMM, // 000 1000 1 1100 + OP_LDRSB_M_REG_OFF,// 000 1000 1 1101 + OP_TST_ROR_IMM, // 000 1000 1 1110 + OP_LDRSH_M_REG_OFF,// 000 1000 1 1111 +//------------------------------------------ + OP_MSR_CPSR, // 000 1001 0 0000 + OP_BX, // 000 1001 0 0001 + OP_UND, // 000 1001 0 0010 + OP_BLX_REG, // 000 1001 0 0011 + OP_UND, // 000 1001 0 0100 + OP_QSUB, // 000 1001 0 0101 + OP_UND, // 000 1001 0 0110 + OP_BKPT, // 000 1001 0 0111 + + OP_SMLAW_B, // 000 1001 0 1000 + OP_UND, // 000 1001 0 1001 + OP_SMULW_B, // 000 1001 0 1010 + OP_STRH_PRE_INDE_M_REG_OFF, // 000 1001 0 1011 + OP_SMLAW_T, // 000 1001 0 1100 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1001 0 1101 + OP_SMULW_T, // 000 1001 0 1110 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1001 0 1111 + + OP_TEQ_LSL_IMM, // 000 1001 1 0000 + OP_TEQ_LSL_REG, // 000 1001 1 0001 + OP_TEQ_LSR_IMM, // 000 1001 1 0010 + OP_TEQ_LSR_REG, // 000 1001 1 0011 + OP_TEQ_ASR_IMM, // 000 1001 1 0100 + OP_TEQ_ASR_REG, // 000 1001 1 0101 + OP_TEQ_ROR_IMM, // 000 1001 1 0110 + OP_TEQ_ROR_REG, // 000 1001 1 0111 + + OP_TEQ_LSL_IMM, // 000 1001 1 1000 + OP_UND, // 000 1001 1 1001 + OP_TEQ_LSR_IMM, // OOO 1001 1 1010 + OP_LDRH_PRE_INDE_M_REG_OFF, // 000 1001 1 1011 + OP_TEQ_ASR_IMM, // 000 1001 1 1100 + OP_LDRSB_PRE_INDE_M_REG_OFF, // 000 1001 1 1101 + OP_TEQ_ROR_IMM, // 000 1001 1 1110 + OP_LDRSH_PRE_INDE_M_REG_OFF, // 000 1001 1 1111 +//------------------------------------------ + OP_MRS_SPSR, // 000 1010 0 0000 + OP_UND, // 000 1010 0 0001 + OP_UND, // 000 1010 0 0010 + OP_UND, // 000 1010 0 0011 + OP_UND, // 000 1010 0 0100 + OP_QDADD, // 000 1010 0 0101 + OP_UND, // 000 1010 0 0110 + OP_UND, // 000 1010 0 0111 + + OP_SMLAL_B_B, // 000 1010 0 1000 + OP_SWPB, // 000 1010 0 1001 + OP_SMLAL_T_B, // 000 1010 0 1010 + OP_STRH_M_IMM_OFF, // 000 1010 0 1011 + OP_SMLAL_B_T, // 000 1010 0 1100 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1010 0 1101 + OP_SMLAL_T_T, // 000 1010 0 1110 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1010 0 1111 + + OP_CMP_LSL_IMM, // 000 1010 1 0000 + OP_CMP_LSL_REG, // 000 1010 1 0001 + OP_CMP_LSR_IMM, // 000 1010 1 0010 + OP_CMP_LSR_REG, // 000 1010 1 0011 + OP_CMP_ASR_IMM, // 000 1010 1 0100 + OP_CMP_ASR_REG, // 000 1010 1 0101 + OP_CMP_ROR_IMM, // 000 1010 1 0110 + OP_CMP_ROR_REG, // 000 1010 1 0111 + + OP_CMP_LSL_IMM, // 000 1010 1 1000 + OP_UND, // 000 1010 1 1001 + OP_CMP_LSR_IMM, // OOO 1O1O 1 1010 + OP_LDRH_M_IMM_OFF, // 000 1010 1 1011 + OP_CMP_ASR_IMM, // 000 1010 1 1100 + OP_LDRSB_M_IMM_OFF,// 000 1010 1 1101 + OP_CMP_ROR_IMM, // 000 1010 1 1110 + OP_LDRSH_M_IMM_OFF,// 000 1010 1 1111 +//------------------------------------------ + OP_MSR_SPSR, // 000 1011 0 0000 + OP_CLZ, // 000 1011 0 0001 + OP_UND, // 000 1011 0 0010 + OP_UND, // 000 1011 0 0011 + OP_UND, // 000 1011 0 0100 + OP_QDSUB, // 000 1011 0 0101 + OP_UND, // 000 1011 0 0110 + OP_UND, // 000 1011 0 0111 + + OP_SMUL_B_B, // 000 1011 0 1000 + OP_UND, // 000 1011 0 1001 + OP_SMUL_T_B, // 000 1011 0 1010 + OP_STRH_PRE_INDE_M_IMM_OFF, // 000 1011 0 1011 + OP_SMUL_B_T, // 000 1011 0 1100 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1011 0 1101 + OP_SMUL_T_T, // 000 1011 0 1110 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1011 0 1111 + + OP_CMN_LSL_IMM, // 000 1011 1 0000 + OP_CMN_LSL_REG, // 000 1011 1 0001 + OP_CMN_LSR_IMM, // 000 1011 1 0010 + OP_CMN_LSR_REG, // 000 1011 1 0011 + OP_CMN_ASR_IMM, // 000 1011 1 0100 + OP_CMN_ASR_REG, // 000 1011 1 0101 + OP_CMN_ROR_IMM, // 000 1011 1 0110 + OP_CMN_ROR_REG, // 000 1011 1 0111 + + OP_CMN_LSL_IMM, // 000 1011 1 1000 + OP_UND, // 000 1011 1 1001 + OP_CMN_LSR_IMM, // OOO 1O11 1 1010 + OP_LDRH_PRE_INDE_M_IMM_OFF, // 000 1011 1 1011 + OP_CMN_ASR_IMM, // 000 1011 1 1100 + OP_LDRSB_PRE_INDE_M_IMM_OFF, // 000 1011 1 1101 + OP_CMN_ROR_IMM, // 000 1011 1 1110 + OP_LDRSH_PRE_INDE_M_IMM_OFF, // 000 1011 1 1111 +//------------------------------------------ + OP_ORR_LSL_IMM, // 000 1100 0 0000 + OP_ORR_LSL_REG, // 000 1100 0 0001 + OP_ORR_LSR_IMM, // 000 1100 0 0010 + OP_ORR_LSR_REG, // 000 1100 0 0011 + OP_ORR_ASR_IMM, // 000 1100 0 0100 + OP_ORR_ASR_REG, // 000 1100 0 0101 + OP_ORR_ROR_IMM, // 000 1100 0 0110 + OP_ORR_ROR_REG, // 000 1100 0 0111 + + OP_ORR_LSL_IMM, // 000 1100 0 1000 + OP_UND, // 000 1100 0 1001 + OP_ORR_LSR_IMM, // OOO 110O O 1010 + OP_STRH_P_REG_OFF, // 000 1100 0 1011 + OP_ORR_ASR_IMM, // 000 1100 0 1100 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1100 0 1101 + OP_ORR_ROR_IMM, // 000 1100 0 1110 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1100 0 1111 + + OP_ORR_S_LSL_IMM, // 000 1100 1 0000 + OP_ORR_S_LSL_REG, // 000 1100 1 0001 + OP_ORR_S_LSR_IMM, // 000 1100 1 0010 + OP_ORR_S_LSR_REG, // 000 1100 1 0011 + OP_ORR_S_ASR_IMM, // 000 1100 1 0100 + OP_ORR_S_ASR_REG, // 000 1100 1 0101 + OP_ORR_S_ROR_IMM, // 000 1100 1 0110 + OP_ORR_S_ROR_REG, // 000 1100 1 0111 + + OP_ORR_S_LSL_IMM, // 000 1100 1 1000 + OP_UND, // 000 1100 1 1001 + OP_ORR_S_LSR_IMM, // 000 1100 1 1010 + OP_LDRH_P_REG_OFF, // 000 1100 1 1011 + OP_ORR_S_ASR_IMM, // 000 1100 1 1100 + OP_LDRSB_P_REG_OFF,// 000 1100 1 1101 + OP_ORR_S_ROR_IMM, // 000 1100 1 1110 + OP_LDRSH_P_REG_OFF,// 000 1100 1 1111 +//------------------------------------------ + OP_MOV_LSL_IMM, // 000 1101 0 0000 + OP_MOV_LSL_REG, // 000 1101 0 0001 + OP_MOV_LSR_IMM, // 000 1101 0 0010 + OP_MOV_LSR_REG, // 000 1101 0 0011 + OP_MOV_ASR_IMM, // 000 1101 0 0100 + OP_MOV_ASR_REG, // 000 1101 0 0101 + OP_MOV_ROR_IMM, // 000 1101 0 0110 + OP_MOV_ROR_REG, // 000 1101 0 0111 + + OP_MOV_LSL_IMM, // 000 1101 0 1000 + OP_UND, // 000 1101 0 1001 + OP_MOV_LSR_IMM, // OOO 1101 O 1010 + OP_STRH_PRE_INDE_P_REG_OFF, // 000 1101 0 1011 + OP_MOV_ASR_IMM, // 000 1101 0 1100 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1101 0 1101 + OP_MOV_ROR_IMM, // 000 1101 0 1110 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1101 0 1111 + + OP_MOV_S_LSL_IMM, // 000 1101 1 0000 + OP_MOV_S_LSL_REG, // 000 1101 1 0001 + OP_MOV_S_LSR_IMM, // 000 1101 1 0010 + OP_MOV_S_LSR_REG, // 000 1101 1 0011 + OP_MOV_S_ASR_IMM, // 000 1101 1 0100 + OP_MOV_S_ASR_REG, // 000 1101 1 0101 + OP_MOV_S_ROR_IMM, // 000 1101 1 0110 + OP_MOV_S_ROR_REG, // 000 1101 1 0111 + + OP_MOV_S_LSL_IMM, // 000 1101 1 1000 + OP_UND, // 000 1101 1 1001 + OP_MOV_S_LSR_IMM, // 000 1101 1 1010 + OP_LDRH_PRE_INDE_P_REG_OFF, // 000 1101 1 1011 + OP_MOV_S_ASR_IMM, // 000 1101 1 1100 + OP_LDRSB_PRE_INDE_P_REG_OFF,// 000 1101 1 1101 + OP_MOV_S_ROR_IMM, // 000 1101 1 1110 + OP_LDRSH_PRE_INDE_P_REG_OFF,// 000 1101 1 1111 +//------------------------------------------ + OP_BIC_LSL_IMM, // 000 1110 0 0000 + OP_BIC_LSL_REG, // 000 1110 0 0001 + OP_BIC_LSR_IMM, // 000 1110 0 0010 + OP_BIC_LSR_REG, // 000 1110 0 0011 + OP_BIC_ASR_IMM, // 000 1110 0 0100 + OP_BIC_ASR_REG, // 000 1110 0 0101 + OP_BIC_ROR_IMM, // 000 1110 0 0110 + OP_BIC_ROR_REG, // 000 1110 0 0111 + + OP_BIC_LSL_IMM, // 000 1110 0 1000 + OP_UND, // 000 1110 0 1001 + OP_BIC_LSR_IMM, // OOO 111O O 1010 + OP_STRH_P_IMM_OFF, // 000 1110 0 1011 + OP_BIC_ASR_IMM, // 000 1110 0 1100 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1110 0 1101 + OP_BIC_ROR_IMM, // 000 1110 0 1110 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1110 0 1111 + + OP_BIC_S_LSL_IMM, // 000 1110 1 0000 + OP_BIC_S_LSL_REG, // 000 1110 1 0001 + OP_BIC_S_LSR_IMM, // 000 1110 1 0010 + OP_BIC_S_LSR_REG, // 000 1110 1 0011 + OP_BIC_S_ASR_IMM, // 000 1110 1 0100 + OP_BIC_S_ASR_REG, // 000 1110 1 0101 + OP_BIC_S_ROR_IMM, // 000 1110 1 0110 + OP_BIC_S_ROR_REG, // 000 1110 1 0111 + + OP_BIC_S_LSL_IMM, // 000 1110 1 1000 + OP_UND, // 000 1110 1 1001 + OP_BIC_S_LSR_IMM, // 000 1110 1 1010 + OP_LDRH_P_IMM_OFF, // 000 1110 1 1011 + OP_BIC_S_ASR_IMM, // 000 1110 1 1100 + OP_LDRSB_P_IMM_OFF,// 000 1110 1 1101 + OP_BIC_S_ROR_IMM, // 000 1110 1 1110 + OP_LDRSH_P_IMM_OFF,// 000 1110 1 1111 +//------------------------------------------- + OP_MVN_LSL_IMM, // 000 1111 0 0000 + OP_MVN_LSL_REG, // 000 1111 0 0001 + OP_MVN_LSR_IMM, // 000 1111 0 0010 + OP_MVN_LSR_REG, // 000 1111 0 0011 + OP_MVN_ASR_IMM, // 000 1111 0 0100 + OP_MVN_ASR_REG, // 000 1111 0 0101 + OP_MVN_ROR_IMM, // 000 1111 0 0110 + OP_MVN_ROR_REG, // 000 1111 0 0111 + + OP_MVN_LSL_IMM, // 000 1111 0 1000 + OP_UND, // 000 1111 0 1001 + OP_MVN_LSR_IMM, // OOO 1111 O 1010 + OP_STRH_PRE_INDE_P_IMM_OFF, // 000 1111 0 1011 + OP_MVN_ASR_IMM, // 000 1111 0 1100 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1111 0 1101 + OP_MVN_ROR_IMM, // 000 1111 0 1110 + OP_LDRD_STRD_OFFSET_PRE_INDEX, + // 000 1111 0 1111 + + OP_MVN_S_LSL_IMM, // 000 1111 1 0000 + OP_MVN_S_LSL_REG, // 000 1111 1 0001 + OP_MVN_S_LSR_IMM, // 000 1111 1 0010 + OP_MVN_S_LSR_REG, // 000 1111 1 0011 + OP_MVN_S_ASR_IMM, // 000 1111 1 0100 + OP_MVN_S_ASR_REG, // 000 1111 1 0101 + OP_MVN_S_ROR_IMM, // 000 1111 1 0110 + OP_MVN_S_ROR_REG, // 000 1111 1 0111 + + OP_MVN_S_LSL_IMM, // 000 1111 1 1000 + OP_UND, // 000 1111 1 1001 + OP_MVN_S_LSR_IMM, // 000 1111 1 1010 + OP_LDRH_PRE_INDE_P_IMM_OFF, // 000 1111 1 1011 + OP_MVN_S_ASR_IMM, // 000 1111 1 1100 + OP_LDRSB_PRE_INDE_P_IMM_OFF,// 000 1111 1 1101 + OP_MVN_S_ROR_IMM, // 000 1111 1 1110 + OP_LDRSH_PRE_INDE_P_IMM_OFF,// 000 1111 1 1111 +//------------------------------------------- + OP_AND_IMM_VAL, // 001 0000 0 0000 + OP_AND_IMM_VAL, // 001 0000 0 0001 + OP_AND_IMM_VAL, // 001 0000 0 0010 + OP_AND_IMM_VAL, // 001 0000 0 0011 + OP_AND_IMM_VAL, // 001 0000 0 0100 + OP_AND_IMM_VAL, // 001 0000 0 0101 + OP_AND_IMM_VAL, // 001 0000 0 0110 + OP_AND_IMM_VAL, // 001 0000 0 0111 + OP_AND_IMM_VAL, // 001 0000 0 1000 + OP_AND_IMM_VAL, // 001 0000 0 1001 + OP_AND_IMM_VAL, // 001 0000 0 1010 + OP_AND_IMM_VAL, // 001 0000 0 1011 + OP_AND_IMM_VAL, // 001 0000 0 1100 + OP_AND_IMM_VAL, // 001 0000 0 1101 + OP_AND_IMM_VAL, // 001 0000 0 1110 + OP_AND_IMM_VAL, // 001 0000 0 1111 + + OP_AND_S_IMM_VAL, // 001 0000 1 0000 + OP_AND_S_IMM_VAL, // 001 0000 1 0001 + OP_AND_S_IMM_VAL, // 001 0000 1 0010 + OP_AND_S_IMM_VAL, // 001 0000 1 0011 + OP_AND_S_IMM_VAL, // 001 0000 1 0100 + OP_AND_S_IMM_VAL, // 001 0000 1 0101 + OP_AND_S_IMM_VAL, // 001 0000 1 0110 + OP_AND_S_IMM_VAL, // 001 0000 1 0111 + OP_AND_S_IMM_VAL, // 001 0000 1 1000 + OP_AND_S_IMM_VAL, // 001 0000 1 1001 + OP_AND_S_IMM_VAL, // 001 0000 1 1010 + OP_AND_S_IMM_VAL, // 001 0000 1 1011 + OP_AND_S_IMM_VAL, // 001 0000 1 1100 + OP_AND_S_IMM_VAL, // 001 0000 1 1101 + OP_AND_S_IMM_VAL, // 001 0000 1 1110 + OP_AND_S_IMM_VAL, // 001 0000 1 1111 +//------------------------------------------ + OP_EOR_IMM_VAL, // 001 0001 0 0000 + OP_EOR_IMM_VAL, // 001 0001 0 0001 + OP_EOR_IMM_VAL, // 001 0001 0 0010 + OP_EOR_IMM_VAL, // 001 0001 0 0011 + OP_EOR_IMM_VAL, // 001 0001 0 0100 + OP_EOR_IMM_VAL, // 001 0001 0 0101 + OP_EOR_IMM_VAL, // 001 0001 0 0110 + OP_EOR_IMM_VAL, // 001 0001 0 0111 + OP_EOR_IMM_VAL, // 001 0001 0 1000 + OP_EOR_IMM_VAL, // 001 0001 0 1001 + OP_EOR_IMM_VAL, // 001 0001 0 1010 + OP_EOR_IMM_VAL, // 001 0001 0 1011 + OP_EOR_IMM_VAL, // 001 0001 0 1100 + OP_EOR_IMM_VAL, // 001 0001 0 1101 + OP_EOR_IMM_VAL, // 001 0001 0 1110 + OP_EOR_IMM_VAL, // 001 0001 0 1111 + + OP_EOR_S_IMM_VAL, // 001 0001 1 0000 + OP_EOR_S_IMM_VAL, // 001 0001 1 0001 + OP_EOR_S_IMM_VAL, // 001 0001 1 0010 + OP_EOR_S_IMM_VAL, // 001 0001 1 0011 + OP_EOR_S_IMM_VAL, // 001 0001 1 0100 + OP_EOR_S_IMM_VAL, // 001 0001 1 0101 + OP_EOR_S_IMM_VAL, // 001 0001 1 0110 + OP_EOR_S_IMM_VAL, // 001 0001 1 0111 + OP_EOR_S_IMM_VAL, // 001 0001 1 1000 + OP_EOR_S_IMM_VAL, // 001 0001 1 1001 + OP_EOR_S_IMM_VAL, // 001 0001 1 1010 + OP_EOR_S_IMM_VAL, // 001 0001 1 1011 + OP_EOR_S_IMM_VAL, // 001 0001 1 1100 + OP_EOR_S_IMM_VAL, // 001 0001 1 1101 + OP_EOR_S_IMM_VAL, // 001 0001 1 1110 + OP_EOR_S_IMM_VAL, // 001 0001 1 1111 +//------------------------------------------ + OP_SUB_IMM_VAL, // 001 0010 0 0000 + OP_SUB_IMM_VAL, // 001 0010 0 0001 + OP_SUB_IMM_VAL, // 001 0010 0 0010 + OP_SUB_IMM_VAL, // 001 0010 0 0011 + OP_SUB_IMM_VAL, // 001 0010 0 0100 + OP_SUB_IMM_VAL, // 001 0010 0 0101 + OP_SUB_IMM_VAL, // 001 0010 0 0110 + OP_SUB_IMM_VAL, // 001 0010 0 0111 + OP_SUB_IMM_VAL, // 001 0010 0 1000 + OP_SUB_IMM_VAL, // 001 0010 0 1001 + OP_SUB_IMM_VAL, // 001 0010 0 1010 + OP_SUB_IMM_VAL, // 001 0010 0 1011 + OP_SUB_IMM_VAL, // 001 0010 0 1100 + OP_SUB_IMM_VAL, // 001 0010 0 1101 + OP_SUB_IMM_VAL, // 001 0010 0 1110 + OP_SUB_IMM_VAL, // 001 0010 0 1111 + + OP_SUB_S_IMM_VAL, // 001 0010 1 0000 + OP_SUB_S_IMM_VAL, // 001 0010 1 0001 + OP_SUB_S_IMM_VAL, // 001 0010 1 0010 + OP_SUB_S_IMM_VAL, // 001 0010 1 0011 + OP_SUB_S_IMM_VAL, // 001 0010 1 0100 + OP_SUB_S_IMM_VAL, // 001 0010 1 0101 + OP_SUB_S_IMM_VAL, // 001 0010 1 0110 + OP_SUB_S_IMM_VAL, // 001 0010 1 0111 + OP_SUB_S_IMM_VAL, // 001 0010 1 1000 + OP_SUB_S_IMM_VAL, // 001 0010 1 1001 + OP_SUB_S_IMM_VAL, // 001 0010 1 1010 + OP_SUB_S_IMM_VAL, // 001 0010 1 1011 + OP_SUB_S_IMM_VAL, // 001 0010 1 1100 + OP_SUB_S_IMM_VAL, // 001 0010 1 1101 + OP_SUB_S_IMM_VAL, // 001 0010 1 1110 + OP_SUB_S_IMM_VAL, // 001 0010 1 1111 +//------------------------------------------ + OP_RSB_IMM_VAL, // 001 0011 0 0000 + OP_RSB_IMM_VAL, // 001 0011 0 0001 + OP_RSB_IMM_VAL, // 001 0011 0 0010 + OP_RSB_IMM_VAL, // 001 0011 0 0011 + OP_RSB_IMM_VAL, // 001 0011 0 0100 + OP_RSB_IMM_VAL, // 001 0011 0 0101 + OP_RSB_IMM_VAL, // 001 0011 0 0110 + OP_RSB_IMM_VAL, // 001 0011 0 0111 + OP_RSB_IMM_VAL, // 001 0011 0 1000 + OP_RSB_IMM_VAL, // 001 0011 0 1001 + OP_RSB_IMM_VAL, // 001 0011 0 1010 + OP_RSB_IMM_VAL, // 001 0011 0 1011 + OP_RSB_IMM_VAL, // 001 0011 0 1100 + OP_RSB_IMM_VAL, // 001 0011 0 1101 + OP_RSB_IMM_VAL, // 001 0011 0 1110 + OP_RSB_IMM_VAL, // 001 0011 0 1111 + + OP_RSB_S_IMM_VAL, // 001 0011 1 0000 + OP_RSB_S_IMM_VAL, // 001 0011 1 0001 + OP_RSB_S_IMM_VAL, // 001 0011 1 0010 + OP_RSB_S_IMM_VAL, // 001 0011 1 0011 + OP_RSB_S_IMM_VAL, // 001 0011 1 0100 + OP_RSB_S_IMM_VAL, // 001 0011 1 0101 + OP_RSB_S_IMM_VAL, // 001 0011 1 0110 + OP_RSB_S_IMM_VAL, // 001 0011 1 0111 + OP_RSB_S_IMM_VAL, // 001 0011 1 1000 + OP_RSB_S_IMM_VAL, // 001 0011 1 1001 + OP_RSB_S_IMM_VAL, // 001 0011 1 1010 + OP_RSB_S_IMM_VAL, // 001 0011 1 1011 + OP_RSB_S_IMM_VAL, // 001 0011 1 1100 + OP_RSB_S_IMM_VAL, // 001 0011 1 1101 + OP_RSB_S_IMM_VAL, // 001 0011 1 1110 + OP_RSB_S_IMM_VAL, // 001 0011 1 1111 +//------------------------------------------ + OP_ADD_IMM_VAL, // 001 0100 0 0000 + OP_ADD_IMM_VAL, // 001 0100 0 0001 + OP_ADD_IMM_VAL, // 001 0100 0 0010 + OP_ADD_IMM_VAL, // 001 0100 0 0011 + OP_ADD_IMM_VAL, // 001 0100 0 0100 + OP_ADD_IMM_VAL, // 001 0100 0 0101 + OP_ADD_IMM_VAL, // 001 0100 0 0110 + OP_ADD_IMM_VAL, // 001 0100 0 0111 + OP_ADD_IMM_VAL, // 001 0100 0 1000 + OP_ADD_IMM_VAL, // 001 0100 0 1001 + OP_ADD_IMM_VAL, // 001 0100 0 1010 + OP_ADD_IMM_VAL, // 001 0100 0 1011 + OP_ADD_IMM_VAL, // 001 0100 0 1100 + OP_ADD_IMM_VAL, // 001 0100 0 1101 + OP_ADD_IMM_VAL, // 001 0100 0 1110 + OP_ADD_IMM_VAL, // 001 0100 0 1111 + + OP_ADD_S_IMM_VAL, // 001 0100 1 0000 + OP_ADD_S_IMM_VAL, // 001 0100 1 0001 + OP_ADD_S_IMM_VAL, // 001 0100 1 0010 + OP_ADD_S_IMM_VAL, // 001 0100 1 0011 + OP_ADD_S_IMM_VAL, // 001 0100 1 0100 + OP_ADD_S_IMM_VAL, // 001 0100 1 0101 + OP_ADD_S_IMM_VAL, // 001 0100 1 0110 + OP_ADD_S_IMM_VAL, // 001 0100 1 0111 + OP_ADD_S_IMM_VAL, // 001 0100 1 1000 + OP_ADD_S_IMM_VAL, // 001 0100 1 1001 + OP_ADD_S_IMM_VAL, // 001 0100 1 1010 + OP_ADD_S_IMM_VAL, // 001 0100 1 1011 + OP_ADD_S_IMM_VAL, // 001 0100 1 1100 + OP_ADD_S_IMM_VAL, // 001 0100 1 1101 + OP_ADD_S_IMM_VAL, // 001 0100 1 1110 + OP_ADD_S_IMM_VAL, // 001 0100 1 1111 +//------------------------------------------ + OP_ADC_IMM_VAL, // 001 0101 0 0000 + OP_ADC_IMM_VAL, // 001 0101 0 0001 + OP_ADC_IMM_VAL, // 001 0101 0 0010 + OP_ADC_IMM_VAL, // 001 0101 0 0011 + OP_ADC_IMM_VAL, // 001 0101 0 0100 + OP_ADC_IMM_VAL, // 001 0101 0 0101 + OP_ADC_IMM_VAL, // 001 0101 0 0110 + OP_ADC_IMM_VAL, // 001 0101 0 0111 + OP_ADC_IMM_VAL, // 001 0101 0 1000 + OP_ADC_IMM_VAL, // 001 0101 0 1001 + OP_ADC_IMM_VAL, // 001 0101 0 1010 + OP_ADC_IMM_VAL, // 001 0101 0 1011 + OP_ADC_IMM_VAL, // 001 0101 0 1100 + OP_ADC_IMM_VAL, // 001 0101 0 1101 + OP_ADC_IMM_VAL, // 001 0101 0 1110 + OP_ADC_IMM_VAL, // 001 0101 0 1111 + + OP_ADC_S_IMM_VAL, // 001 0101 1 0000 + OP_ADC_S_IMM_VAL, // 001 0101 1 0001 + OP_ADC_S_IMM_VAL, // 001 0101 1 0010 + OP_ADC_S_IMM_VAL, // 001 0101 1 0011 + OP_ADC_S_IMM_VAL, // 001 0101 1 0100 + OP_ADC_S_IMM_VAL, // 001 0101 1 0101 + OP_ADC_S_IMM_VAL, // 001 0101 1 0110 + OP_ADC_S_IMM_VAL, // 001 0101 1 0111 + OP_ADC_S_IMM_VAL, // 001 0101 1 1000 + OP_ADC_S_IMM_VAL, // 001 0101 1 1001 + OP_ADC_S_IMM_VAL, // 001 0101 1 1010 + OP_ADC_S_IMM_VAL, // 001 0101 1 1011 + OP_ADC_S_IMM_VAL, // 001 0101 1 1100 + OP_ADC_S_IMM_VAL, // 001 0101 1 1101 + OP_ADC_S_IMM_VAL, // 001 0101 1 1110 + OP_ADC_S_IMM_VAL, // 001 0101 1 1111 +//------------------------------------------ + OP_SBC_IMM_VAL, // 001 0110 0 0000 + OP_SBC_IMM_VAL, // 001 0110 0 0001 + OP_SBC_IMM_VAL, // 001 0110 0 0010 + OP_SBC_IMM_VAL, // 001 0110 0 0011 + OP_SBC_IMM_VAL, // 001 0110 0 0100 + OP_SBC_IMM_VAL, // 001 0110 0 0101 + OP_SBC_IMM_VAL, // 001 0110 0 0110 + OP_SBC_IMM_VAL, // 001 0110 0 0111 + OP_SBC_IMM_VAL, // 001 0110 0 1000 + OP_SBC_IMM_VAL, // 001 0110 0 1001 + OP_SBC_IMM_VAL, // 001 0110 0 1010 + OP_SBC_IMM_VAL, // 001 0110 0 1011 + OP_SBC_IMM_VAL, // 001 0110 0 1100 + OP_SBC_IMM_VAL, // 001 0110 0 1101 + OP_SBC_IMM_VAL, // 001 0110 0 1110 + OP_SBC_IMM_VAL, // 001 0110 0 1111 + + OP_SBC_S_IMM_VAL, // 001 0110 1 0000 + OP_SBC_S_IMM_VAL, // 001 0110 1 0001 + OP_SBC_S_IMM_VAL, // 001 0110 1 0010 + OP_SBC_S_IMM_VAL, // 001 0110 1 0011 + OP_SBC_S_IMM_VAL, // 001 0110 1 0100 + OP_SBC_S_IMM_VAL, // 001 0110 1 0101 + OP_SBC_S_IMM_VAL, // 001 0110 1 0110 + OP_SBC_S_IMM_VAL, // 001 0110 1 0111 + OP_SBC_S_IMM_VAL, // 001 0110 1 1000 + OP_SBC_S_IMM_VAL, // 001 0110 1 1001 + OP_SBC_S_IMM_VAL, // 001 0110 1 1010 + OP_SBC_S_IMM_VAL, // 001 0110 1 1011 + OP_SBC_S_IMM_VAL, // 001 0110 1 1100 + OP_SBC_S_IMM_VAL, // 001 0110 1 1101 + OP_SBC_S_IMM_VAL, // 001 0110 1 1110 + OP_SBC_S_IMM_VAL, // 001 0110 1 1111 +//------------------------------------------ + OP_RSC_IMM_VAL, // 001 0111 0 0000 + OP_RSC_IMM_VAL, // 001 0111 0 0001 + OP_RSC_IMM_VAL, // 001 0111 0 0010 + OP_RSC_IMM_VAL, // 001 0111 0 0011 + OP_RSC_IMM_VAL, // 001 0111 0 0100 + OP_RSC_IMM_VAL, // 001 0111 0 0101 + OP_RSC_IMM_VAL, // 001 0111 0 0110 + OP_RSC_IMM_VAL, // 001 0111 0 0111 + OP_RSC_IMM_VAL, // 001 0111 0 1000 + OP_RSC_IMM_VAL, // 001 0111 0 1001 + OP_RSC_IMM_VAL, // 001 0111 0 1010 + OP_RSC_IMM_VAL, // 001 0111 0 1011 + OP_RSC_IMM_VAL, // 001 0111 0 1100 + OP_RSC_IMM_VAL, // 001 0111 0 1101 + OP_RSC_IMM_VAL, // 001 0111 0 1110 + OP_RSC_IMM_VAL, // 001 0111 0 1111 + + OP_RSC_S_IMM_VAL, // 001 0111 1 0000 + OP_RSC_S_IMM_VAL, // 001 0111 1 0001 + OP_RSC_S_IMM_VAL, // 001 0111 1 0010 + OP_RSC_S_IMM_VAL, // 001 0111 1 0011 + OP_RSC_S_IMM_VAL, // 001 0111 1 0100 + OP_RSC_S_IMM_VAL, // 001 0111 1 0101 + OP_RSC_S_IMM_VAL, // 001 0111 1 0110 + OP_RSC_S_IMM_VAL, // 001 0111 1 0111 + OP_RSC_S_IMM_VAL, // 001 0111 1 1000 + OP_RSC_S_IMM_VAL, // 001 0111 1 1001 + OP_RSC_S_IMM_VAL, // 001 0111 1 1010 + OP_RSC_S_IMM_VAL, // 001 0111 1 1011 + OP_RSC_S_IMM_VAL, // 001 0111 1 1100 + OP_RSC_S_IMM_VAL, // 001 0111 1 1101 + OP_RSC_S_IMM_VAL, // 001 0111 1 1110 + OP_RSC_S_IMM_VAL, // 001 0111 1 1111 +//------------------------------------------ + OP_UND, // 001 1000 0 0000 + OP_UND, // 001 1000 0 0001 + OP_UND, // 001 1000 0 0010 + OP_UND, // 001 1000 0 0011 + OP_UND, // 001 1000 0 0100 + OP_UND, // 001 1000 0 0101 + OP_UND, // 001 1000 0 0110 + OP_UND, // 001 1000 0 0111 + OP_UND, // 001 1000 0 1000 + OP_UND, // 001 1000 0 1001 + OP_UND, // 001 1000 0 1010 + OP_UND, // 001 1000 0 1011 + OP_UND, // 001 1000 0 1100 + OP_UND, // 001 1000 0 1101 + OP_UND, // 001 1000 0 1110 + OP_UND, // 001 1000 0 1111 + + OP_TST_IMM_VAL, // 001 1000 1 0000 + OP_TST_IMM_VAL, // 001 1000 1 0001 + OP_TST_IMM_VAL, // 001 1000 1 0010 + OP_TST_IMM_VAL, // 001 1000 1 0011 + OP_TST_IMM_VAL, // 001 1000 1 0100 + OP_TST_IMM_VAL, // 001 1000 1 0101 + OP_TST_IMM_VAL, // 001 1000 1 0110 + OP_TST_IMM_VAL, // 001 1000 1 0111 + OP_TST_IMM_VAL, // 001 1000 1 1000 + OP_TST_IMM_VAL, // 001 1000 1 1001 + OP_TST_IMM_VAL, // 001 1000 1 1010 + OP_TST_IMM_VAL, // 001 1000 1 1011 + OP_TST_IMM_VAL, // 001 1000 1 1100 + OP_TST_IMM_VAL, // 001 1000 1 1101 + OP_TST_IMM_VAL, // 001 1000 1 1110 + OP_TST_IMM_VAL, // 001 1000 1 1111 +//------------------------------------------ + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 0000 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 0001 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 0010 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 0011 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 0100 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 0101 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 0110 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 0111 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 1000 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 1001 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 1010 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 1011 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 1100 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 1101 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 1110 + OP_MSR_CPSR_IMM_VAL, // 001 1001 0 1111 + + OP_TEQ_IMM_VAL, // 001 1001 1 0000 + OP_TEQ_IMM_VAL, // 001 1001 1 0001 + OP_TEQ_IMM_VAL, // 001 1001 1 0010 + OP_TEQ_IMM_VAL, // 001 1001 1 0011 + OP_TEQ_IMM_VAL, // 001 1001 1 0100 + OP_TEQ_IMM_VAL, // 001 1001 1 0101 + OP_TEQ_IMM_VAL, // 001 1001 1 0110 + OP_TEQ_IMM_VAL, // 001 1001 1 0111 + OP_TEQ_IMM_VAL, // 001 1001 1 1000 + OP_TEQ_IMM_VAL, // 001 1001 1 1001 + OP_TEQ_IMM_VAL, // 001 1001 1 1010 + OP_TEQ_IMM_VAL, // 001 1001 1 1011 + OP_TEQ_IMM_VAL, // 001 1001 1 1100 + OP_TEQ_IMM_VAL, // 001 1001 1 1101 + OP_TEQ_IMM_VAL, // 001 1001 1 1110 + OP_TEQ_IMM_VAL, // 001 1001 1 1111 +//------------------------------------------ + OP_UND, // 001 1010 0 0000 + OP_UND, // 001 1010 0 0001 + OP_UND, // 001 1010 0 0010 + OP_UND, // 001 1010 0 0011 + OP_UND, // 001 1010 0 0100 + OP_UND, // 001 1010 0 0101 + OP_UND, // 001 1010 0 0110 + OP_UND, // 001 1010 0 0111 + OP_UND, // 001 1010 0 1000 + OP_UND, // 001 1010 0 1001 + OP_UND, // 001 1010 0 1010 + OP_UND, // 001 1010 0 1011 + OP_UND, // 001 1010 0 1100 + OP_UND, // 001 1010 0 1101 + OP_UND, // 001 1010 0 1110 + OP_UND, // 001 1010 0 1111 + + OP_CMP_IMM_VAL, // 001 1010 1 0000 + OP_CMP_IMM_VAL, // 001 1010 1 0001 + OP_CMP_IMM_VAL, // 001 1010 1 0010 + OP_CMP_IMM_VAL, // 001 1010 1 0011 + OP_CMP_IMM_VAL, // 001 1010 1 0100 + OP_CMP_IMM_VAL, // 001 1010 1 0101 + OP_CMP_IMM_VAL, // 001 1010 1 0110 + OP_CMP_IMM_VAL, // 001 1010 1 0111 + OP_CMP_IMM_VAL, // 001 1010 1 1000 + OP_CMP_IMM_VAL, // 001 1010 1 1001 + OP_CMP_IMM_VAL, // 001 1010 1 1010 + OP_CMP_IMM_VAL, // 001 1010 1 1011 + OP_CMP_IMM_VAL, // 001 1010 1 1100 + OP_CMP_IMM_VAL, // 001 1010 1 1101 + OP_CMP_IMM_VAL, // 001 1010 1 1110 + OP_CMP_IMM_VAL, // 001 1010 1 1111 +//------------------------------------------ + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 0000 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 0001 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 0010 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 0011 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 0100 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 0101 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 0110 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 0111 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 1000 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 1001 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 1010 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 1011 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 1100 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 1101 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 1110 + OP_MSR_SPSR_IMM_VAL, // 001 1011 0 1111 + + OP_CMN_IMM_VAL, // 001 1011 1 0000 + OP_CMN_IMM_VAL, // 001 1011 1 0001 + OP_CMN_IMM_VAL, // 001 1011 1 0010 + OP_CMN_IMM_VAL, // 001 1011 1 0011 + OP_CMN_IMM_VAL, // 001 1011 1 0100 + OP_CMN_IMM_VAL, // 001 1011 1 0101 + OP_CMN_IMM_VAL, // 001 1011 1 0110 + OP_CMN_IMM_VAL, // 001 1011 1 0111 + OP_CMN_IMM_VAL, // 001 1011 1 1000 + OP_CMN_IMM_VAL, // 001 1011 1 1001 + OP_CMN_IMM_VAL, // 001 1011 1 1010 + OP_CMN_IMM_VAL, // 001 1011 1 1011 + OP_CMN_IMM_VAL, // 001 1011 1 1100 + OP_CMN_IMM_VAL, // 001 1011 1 1101 + OP_CMN_IMM_VAL, // 001 1011 1 1110 + OP_CMN_IMM_VAL, // 001 1011 1 1111 +//------------------------------------------ + OP_ORR_IMM_VAL, // 001 1100 0 0000 + OP_ORR_IMM_VAL, // 001 1100 0 0001 + OP_ORR_IMM_VAL, // 001 1100 0 0010 + OP_ORR_IMM_VAL, // 001 1100 0 0011 + OP_ORR_IMM_VAL, // 001 1100 0 0100 + OP_ORR_IMM_VAL, // 001 1100 0 0101 + OP_ORR_IMM_VAL, // 001 1100 0 0110 + OP_ORR_IMM_VAL, // 001 1100 0 0111 + OP_ORR_IMM_VAL, // 001 1100 0 1000 + OP_ORR_IMM_VAL, // 001 1100 0 1001 + OP_ORR_IMM_VAL, // 001 1100 0 1010 + OP_ORR_IMM_VAL, // 001 1100 0 1011 + OP_ORR_IMM_VAL, // 001 1100 0 1100 + OP_ORR_IMM_VAL, // 001 1100 0 1101 + OP_ORR_IMM_VAL, // 001 1100 0 1110 + OP_ORR_IMM_VAL, // 001 1100 0 1111 + + OP_ORR_S_IMM_VAL, // 001 1100 1 0000 + OP_ORR_S_IMM_VAL, // 001 1100 1 0001 + OP_ORR_S_IMM_VAL, // 001 1100 1 0010 + OP_ORR_S_IMM_VAL, // 001 1100 1 0011 + OP_ORR_S_IMM_VAL, // 001 1100 1 0100 + OP_ORR_S_IMM_VAL, // 001 1100 1 0101 + OP_ORR_S_IMM_VAL, // 001 1100 1 0110 + OP_ORR_S_IMM_VAL, // 001 1100 1 0111 + OP_ORR_S_IMM_VAL, // 001 1100 1 1000 + OP_ORR_S_IMM_VAL, // 001 1100 1 1001 + OP_ORR_S_IMM_VAL, // 001 1100 1 1010 + OP_ORR_S_IMM_VAL, // 001 1100 1 1011 + OP_ORR_S_IMM_VAL, // 001 1100 1 1100 + OP_ORR_S_IMM_VAL, // 001 1100 1 1101 + OP_ORR_S_IMM_VAL, // 001 1100 1 1110 + OP_ORR_S_IMM_VAL, // 001 1100 1 1111 +//------------------------------------------ + OP_MOV_IMM_VAL, // 001 1101 0 0000 + OP_MOV_IMM_VAL, // 001 1101 0 0001 + OP_MOV_IMM_VAL, // 001 1101 0 0010 + OP_MOV_IMM_VAL, // 001 1101 0 0011 + OP_MOV_IMM_VAL, // 001 1101 0 0100 + OP_MOV_IMM_VAL, // 001 1101 0 0101 + OP_MOV_IMM_VAL, // 001 1101 0 0110 + OP_MOV_IMM_VAL, // 001 1101 0 0111 + OP_MOV_IMM_VAL, // 001 1101 0 1000 + OP_MOV_IMM_VAL, // 001 1101 0 1001 + OP_MOV_IMM_VAL, // 001 1101 0 1010 + OP_MOV_IMM_VAL, // 001 1101 0 1011 + OP_MOV_IMM_VAL, // 001 1101 0 1100 + OP_MOV_IMM_VAL, // 001 1101 0 1101 + OP_MOV_IMM_VAL, // 001 1101 0 1110 + OP_MOV_IMM_VAL, // 001 1101 0 1111 + + OP_MOV_S_IMM_VAL, // 001 1101 1 0000 + OP_MOV_S_IMM_VAL, // 001 1101 1 0001 + OP_MOV_S_IMM_VAL, // 001 1101 1 0010 + OP_MOV_S_IMM_VAL, // 001 1101 1 0011 + OP_MOV_S_IMM_VAL, // 001 1101 1 0100 + OP_MOV_S_IMM_VAL, // 001 1101 1 0101 + OP_MOV_S_IMM_VAL, // 001 1101 1 0110 + OP_MOV_S_IMM_VAL, // 001 1101 1 0111 + OP_MOV_S_IMM_VAL, // 001 1101 1 1000 + OP_MOV_S_IMM_VAL, // 001 1101 1 1001 + OP_MOV_S_IMM_VAL, // 001 1101 1 1010 + OP_MOV_S_IMM_VAL, // 001 1101 1 1011 + OP_MOV_S_IMM_VAL, // 001 1101 1 1100 + OP_MOV_S_IMM_VAL, // 001 1101 1 1101 + OP_MOV_S_IMM_VAL, // 001 1101 1 1110 + OP_MOV_S_IMM_VAL, // 001 1101 1 1111 +//------------------------------------------ + OP_BIC_IMM_VAL, // 001 1110 0 0000 + OP_BIC_IMM_VAL, // 001 1110 0 0001 + OP_BIC_IMM_VAL, // 001 1110 0 0010 + OP_BIC_IMM_VAL, // 001 1110 0 0011 + OP_BIC_IMM_VAL, // 001 1110 0 0100 + OP_BIC_IMM_VAL, // 001 1110 0 0101 + OP_BIC_IMM_VAL, // 001 1110 0 0110 + OP_BIC_IMM_VAL, // 001 1110 0 0111 + OP_BIC_IMM_VAL, // 001 1110 0 1000 + OP_BIC_IMM_VAL, // 001 1110 0 1001 + OP_BIC_IMM_VAL, // 001 1110 0 1010 + OP_BIC_IMM_VAL, // 001 1110 0 1011 + OP_BIC_IMM_VAL, // 001 1110 0 1100 + OP_BIC_IMM_VAL, // 001 1110 0 1101 + OP_BIC_IMM_VAL, // 001 1110 0 1110 + OP_BIC_IMM_VAL, // 001 1110 0 1111 + + OP_BIC_S_IMM_VAL, // 001 1110 1 0000 + OP_BIC_S_IMM_VAL, // 001 1110 1 0001 + OP_BIC_S_IMM_VAL, // 001 1110 1 0010 + OP_BIC_S_IMM_VAL, // 001 1110 1 0011 + OP_BIC_S_IMM_VAL, // 001 1110 1 0100 + OP_BIC_S_IMM_VAL, // 001 1110 1 0101 + OP_BIC_S_IMM_VAL, // 001 1110 1 0110 + OP_BIC_S_IMM_VAL, // 001 1110 1 0111 + OP_BIC_S_IMM_VAL, // 001 1110 1 1000 + OP_BIC_S_IMM_VAL, // 001 1110 1 1001 + OP_BIC_S_IMM_VAL, // 001 1110 1 1010 + OP_BIC_S_IMM_VAL, // 001 1110 1 1011 + OP_BIC_S_IMM_VAL, // 001 1110 1 1100 + OP_BIC_S_IMM_VAL, // 001 1110 1 1101 + OP_BIC_S_IMM_VAL, // 001 1110 1 1110 + OP_BIC_S_IMM_VAL, // 001 1110 1 1111 +//------------------------------------------ + OP_MVN_IMM_VAL, // 001 1111 0 0000 + OP_MVN_IMM_VAL, // 001 1111 0 0001 + OP_MVN_IMM_VAL, // 001 1111 0 0010 + OP_MVN_IMM_VAL, // 001 1111 0 0011 + OP_MVN_IMM_VAL, // 001 1111 0 0100 + OP_MVN_IMM_VAL, // 001 1111 0 0101 + OP_MVN_IMM_VAL, // 001 1111 0 0110 + OP_MVN_IMM_VAL, // 001 1111 0 0111 + OP_MVN_IMM_VAL, // 001 1111 0 1000 + OP_MVN_IMM_VAL, // 001 1111 0 1001 + OP_MVN_IMM_VAL, // 001 1111 0 1010 + OP_MVN_IMM_VAL, // 001 1111 0 1011 + OP_MVN_IMM_VAL, // 001 1111 0 1100 + OP_MVN_IMM_VAL, // 001 1111 0 1101 + OP_MVN_IMM_VAL, // 001 1111 0 1110 + OP_MVN_IMM_VAL, // 001 1111 0 1111 + + OP_MVN_S_IMM_VAL, // 001 1111 1 0000 + OP_MVN_S_IMM_VAL, // 001 1111 1 0001 + OP_MVN_S_IMM_VAL, // 001 1111 1 0010 + OP_MVN_S_IMM_VAL, // 001 1111 1 0011 + OP_MVN_S_IMM_VAL, // 001 1111 1 0100 + OP_MVN_S_IMM_VAL, // 001 1111 1 0101 + OP_MVN_S_IMM_VAL, // 001 1111 1 0110 + OP_MVN_S_IMM_VAL, // 001 1111 1 0111 + OP_MVN_S_IMM_VAL, // 001 1111 1 1000 + OP_MVN_S_IMM_VAL, // 001 1111 1 1001 + OP_MVN_S_IMM_VAL, // 001 1111 1 1010 + OP_MVN_S_IMM_VAL, // 001 1111 1 1011 + OP_MVN_S_IMM_VAL, // 001 1111 1 1100 + OP_MVN_S_IMM_VAL, // 001 1111 1 1101 + OP_MVN_S_IMM_VAL, // 001 1111 1 1110 + OP_MVN_S_IMM_VAL, // 001 1111 1 1111 +//------------------------------------------ + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 0000 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 0001 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 0010 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 0011 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 0100 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 0101 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 0110 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 0111 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 1000 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 1001 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 1010 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 1011 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 1100 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 1101 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 1110 + OP_STR_M_IMM_OFF_POSTIND, //010 0000 0 1111 + + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 0000 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 0001 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 0010 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 0011 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 0100 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 0101 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 0110 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 0111 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 1000 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 1001 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 1010 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 1011 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 1100 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 1101 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 1110 + OP_LDR_M_IMM_OFF_POSTIND, //010 0000 1 1111 +//------------------------------------------ + OP_UND, //010 0001 0 0000 + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, +//------------------------------------------ + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 0000 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 0001 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 0010 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 0011 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 0100 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 0101 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 0110 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 0111 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 1000 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 1001 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 1010 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 1011 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 1100 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 1101 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 1110 + OP_STRB_M_IMM_OFF_POSTIND, //010 0010 0 1111 + + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 0000 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 0001 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 0010 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 0011 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 0100 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 0101 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 0110 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 0111 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 1000 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 1001 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 1010 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 1011 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 1100 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 1101 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 1110 + OP_LDRB_M_IMM_OFF_POSTIND, //010 0010 1 1111 +//------------------------------------------ + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_STRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 + OP_LDRBT_M_IMM_OFF_POSTIND, //010 0011 0 0000 +//------------------------------------------ + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND, //010 0100 0 0000 +//------------------------------------------ + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STR_P_IMM_OFF_POSTIND, //010 0100 0 0000 + + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 + OP_LDR_P_IMM_OFF_POSTIND2, //010 0100 0 0000 +//------------------------------------------ + OP_STRB_P_IMM_OFF_POSTIND, //010 0110 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRB_P_IMM_OFF_POSTIND, //010 0110 1 1111 +//------------------------------------------ + OP_STRBT_P_IMM_OFF_POSTIND, //010 0111 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_STRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0100 0 0000 + OP_LDRBT_P_IMM_OFF_POSTIND, //010 0111 1 1111 +//------------------------------------------ + OP_STR_M_IMM_OFF, //010 1000 0 0000 + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + OP_STR_M_IMM_OFF, + + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, + OP_LDR_M_IMM_OFF, //010 1000 1 1111 +//------------------------------------------ + OP_STR_M_IMM_OFF_PREIND, //010 1001 0 0000 + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + OP_STR_M_IMM_OFF_PREIND, + + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, + OP_LDR_M_IMM_OFF_PREIND, //010 1001 1 1111 +//------------------------------------------ + OP_STRB_M_IMM_OFF, //010 1010 0 0000 + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + OP_STRB_M_IMM_OFF, + + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, + OP_LDRB_M_IMM_OFF, //010 1010 1 1111 +//------------------------------------------ + OP_STRB_M_IMM_OFF_PREIND, //010 1011 0 0000 + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + OP_STRB_M_IMM_OFF_PREIND, + + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, + OP_LDRB_M_IMM_OFF_PREIND, //010 1011 1 1111 +//------------------------------------------ + OP_STR_P_IMM_OFF, //010 1100 0 0000 + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + OP_STR_P_IMM_OFF, + + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, + OP_LDR_P_IMM_OFF, //010 1100 1 1111 +//------------------------------------------ + OP_STR_P_IMM_OFF_PREIND, //010 1101 0 0000 + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + OP_STR_P_IMM_OFF_PREIND, + + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, + OP_LDR_P_IMM_OFF_PREIND, //010 1101 1 1111 +//------------------------------------------ + OP_STRB_P_IMM_OFF, //010 1110 0 0000 + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + OP_STRB_P_IMM_OFF, + + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, + OP_LDRB_P_IMM_OFF, //010 1110 1 1111 +//------------------------------------------ + OP_STRB_P_IMM_OFF_PREIND, //010 1111 0 0000 + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + OP_STRB_P_IMM_OFF_PREIND, + + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, + OP_LDRB_P_IMM_OFF_PREIND, //010 1111 1 1111 +//------------------------------------------ + OP_STR_M_LSL_IMM_OFF_POSTIND, //011 0000 0 0000 + OP_UND, + OP_STR_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_M_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_STR_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_M_ROR_IMM_OFF_POSTIND, + OP_UND, + + OP_LDR_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_M_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_M_ROR_IMM_OFF_POSTIND, + OP_UND, //011 0000 1 1111 +//------------------------------------------ + OP_UND, //011 0001 0 0000 + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, //011 0001 1 1111 +//------------------------------------------ + OP_STRB_M_LSL_IMM_OFF_POSTIND, //011 0010 0 0000 + OP_UND, + OP_STRB_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_M_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_M_ROR_IMM_OFF_POSTIND, + OP_UND, + + OP_LDRB_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_M_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_M_ROR_IMM_OFF_POSTIND, + OP_UND, //011 0010 1 1111 +//------------------------------------------ + OP_STRBT_M_LSL_IMM_OFF_POSTIND, //011 0011 0 0000 + OP_UND, + OP_STRBT_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_M_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_M_ROR_IMM_OFF_POSTIND, + OP_UND, + + OP_LDRBT_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_M_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_M_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_M_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_M_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_M_ROR_IMM_OFF_POSTIND, + OP_UND, //011 0011 1 1111 +//------------------------------------------ + OP_STR_P_LSL_IMM_OFF_POSTIND, //011 0100 0 0000 + OP_UND, + OP_STR_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_P_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_STR_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STR_P_ROR_IMM_OFF_POSTIND, + OP_UND, + + OP_LDR_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_P_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDR_P_ROR_IMM_OFF_POSTIND, + OP_UND, //011 0100 1 1111 +//------------------------------------------ + OP_UND, //011 0101 0 0000 + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, + OP_UND, //011 0101 1 1111 +//------------------------------------------ + OP_STRB_P_LSL_IMM_OFF_POSTIND, //011 0110 0 0000 + OP_UND, + OP_STRB_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_P_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STRB_P_ROR_IMM_OFF_POSTIND, + OP_UND, + + OP_LDRB_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_P_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRB_P_ROR_IMM_OFF_POSTIND, + OP_UND, +//------------------------------------------ + OP_STRBT_P_LSL_IMM_OFF_POSTIND, //011 0111 0 0000 + OP_UND, + OP_STRBT_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_P_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_STRBT_P_ROR_IMM_OFF_POSTIND, + OP_UND, + + OP_LDRBT_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_P_ROR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_P_LSL_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_P_LSR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_P_ASR_IMM_OFF_POSTIND, + OP_UND, + OP_LDRBT_P_ROR_IMM_OFF_POSTIND, + OP_UND, +//------------------------------------------ + OP_STR_M_LSL_IMM_OFF, //011 1000 0 0000 + OP_UND, + OP_STR_M_LSR_IMM_OFF, + OP_UND, + OP_STR_M_ASR_IMM_OFF, + OP_UND, + OP_STR_M_ROR_IMM_OFF, + OP_UND, + OP_STR_M_LSL_IMM_OFF, + OP_UND, + OP_STR_M_LSR_IMM_OFF, + OP_UND, + OP_STR_M_ASR_IMM_OFF, + OP_UND, + OP_STR_M_ROR_IMM_OFF, + OP_UND, + + OP_LDR_M_LSL_IMM_OFF, + OP_UND, + OP_LDR_M_LSR_IMM_OFF, + OP_UND, + OP_LDR_M_ASR_IMM_OFF, + OP_UND, + OP_LDR_M_ROR_IMM_OFF, + OP_UND, + OP_LDR_M_LSL_IMM_OFF, + OP_UND, + OP_LDR_M_LSR_IMM_OFF, + OP_UND, + OP_LDR_M_ASR_IMM_OFF, + OP_UND, + OP_LDR_M_ROR_IMM_OFF, + OP_UND, +//------------------------------------------ + OP_STR_M_LSL_IMM_OFF_PREIND, //011 1001 0 0000 + OP_UND, + OP_STR_M_LSR_IMM_OFF_PREIND, + OP_UND, + OP_STR_M_ASR_IMM_OFF_PREIND, + OP_UND, + OP_STR_M_ROR_IMM_OFF_PREIND, + OP_UND, + OP_STR_M_LSL_IMM_OFF_PREIND, + OP_UND, + OP_STR_M_LSR_IMM_OFF_PREIND, + OP_UND, + OP_STR_M_ASR_IMM_OFF_PREIND, + OP_UND, + OP_STR_M_ROR_IMM_OFF_PREIND, + OP_UND, + + OP_LDR_M_LSL_IMM_OFF_PREIND, + OP_UND, + OP_LDR_M_LSR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_M_ASR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_M_ROR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_M_LSL_IMM_OFF_PREIND, + OP_UND, + OP_LDR_M_LSR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_M_ASR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_M_ROR_IMM_OFF_PREIND, + OP_UND, +//------------------------------------------ + OP_STRB_M_LSL_IMM_OFF, //011 1010 0 0000 + OP_UND, + OP_STRB_M_LSR_IMM_OFF, + OP_UND, + OP_STRB_M_ASR_IMM_OFF, + OP_UND, + OP_STRB_M_ROR_IMM_OFF, + OP_UND, + OP_STRB_M_LSL_IMM_OFF, + OP_UND, + OP_STRB_M_LSR_IMM_OFF, + OP_UND, + OP_STRB_M_ASR_IMM_OFF, + OP_UND, + OP_STRB_M_ROR_IMM_OFF, + OP_UND, + + OP_LDRB_M_LSL_IMM_OFF, + OP_UND, + OP_LDRB_M_LSR_IMM_OFF, + OP_UND, + OP_LDRB_M_ASR_IMM_OFF, + OP_UND, + OP_LDRB_M_ROR_IMM_OFF, + OP_UND, + OP_LDRB_M_LSL_IMM_OFF, + OP_UND, + OP_LDRB_M_LSR_IMM_OFF, + OP_UND, + OP_LDRB_M_ASR_IMM_OFF, + OP_UND, + OP_LDRB_M_ROR_IMM_OFF, + OP_UND, +//------------------------------------------ + OP_STRB_M_LSL_IMM_OFF_PREIND, //011 1011 0 0000 + OP_UND, + OP_STRB_M_LSR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_M_ASR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_M_ROR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_M_LSL_IMM_OFF_PREIND, + OP_UND, + OP_STRB_M_LSR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_M_ASR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_M_ROR_IMM_OFF_PREIND, + OP_UND, + + OP_LDRB_M_LSL_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_M_LSR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_M_ASR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_M_ROR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_M_LSL_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_M_LSR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_M_ASR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_M_ROR_IMM_OFF_PREIND, + OP_UND, +//------------------------------------------ + OP_STR_P_LSL_IMM_OFF, //011 1100 0 0000 + OP_UND, + OP_STR_P_LSR_IMM_OFF, + OP_UND, + OP_STR_P_ASR_IMM_OFF, + OP_UND, + OP_STR_P_ROR_IMM_OFF, + OP_UND, + OP_STR_P_LSL_IMM_OFF, + OP_UND, + OP_STR_P_LSR_IMM_OFF, + OP_UND, + OP_STR_P_ASR_IMM_OFF, + OP_UND, + OP_STR_P_ROR_IMM_OFF, + OP_UND, + + OP_LDR_P_LSL_IMM_OFF, + OP_UND, + OP_LDR_P_LSR_IMM_OFF, + OP_UND, + OP_LDR_P_ASR_IMM_OFF, + OP_UND, + OP_LDR_P_ROR_IMM_OFF, + OP_UND, + OP_LDR_P_LSL_IMM_OFF, + OP_UND, + OP_LDR_P_LSR_IMM_OFF, + OP_UND, + OP_LDR_P_ASR_IMM_OFF, + OP_UND, + OP_LDR_P_ROR_IMM_OFF, + OP_UND, +//------------------------------------------ + OP_STR_P_LSL_IMM_OFF_PREIND, //011 1101 0 0000 + OP_UND, + OP_STR_P_LSR_IMM_OFF_PREIND, + OP_UND, + OP_STR_P_ASR_IMM_OFF_PREIND, + OP_UND, + OP_STR_P_ROR_IMM_OFF_PREIND, + OP_UND, + OP_STR_P_LSL_IMM_OFF_PREIND, + OP_UND, + OP_STR_P_LSR_IMM_OFF_PREIND, + OP_UND, + OP_STR_P_ASR_IMM_OFF_PREIND, + OP_UND, + OP_STR_P_ROR_IMM_OFF_PREIND, + OP_UND, + + OP_LDR_P_LSL_IMM_OFF_PREIND, + OP_UND, + OP_LDR_P_LSR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_P_ASR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_P_ROR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_P_LSL_IMM_OFF_PREIND, + OP_UND, + OP_LDR_P_LSR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_P_ASR_IMM_OFF_PREIND, + OP_UND, + OP_LDR_P_ROR_IMM_OFF_PREIND, + OP_UND, +//------------------------------------------ + OP_STRB_P_LSL_IMM_OFF, //011 1110 0 0000 + OP_UND, + OP_STRB_P_LSR_IMM_OFF, + OP_UND, + OP_STRB_P_ASR_IMM_OFF, + OP_UND, + OP_STRB_P_ROR_IMM_OFF, + OP_UND, + OP_STRB_P_LSL_IMM_OFF, + OP_UND, + OP_STRB_P_LSR_IMM_OFF, + OP_UND, + OP_STRB_P_ASR_IMM_OFF, + OP_UND, + OP_STRB_P_ROR_IMM_OFF, + OP_UND, + + OP_LDRB_P_LSL_IMM_OFF, + OP_UND, + OP_LDRB_P_LSR_IMM_OFF, + OP_UND, + OP_LDRB_P_ASR_IMM_OFF, + OP_UND, + OP_LDRB_P_ROR_IMM_OFF, + OP_UND, + OP_LDRB_P_LSL_IMM_OFF, + OP_UND, + OP_LDRB_P_LSR_IMM_OFF, + OP_UND, + OP_LDRB_P_ASR_IMM_OFF, + OP_UND, + OP_LDRB_P_ROR_IMM_OFF, + OP_UND, +//------------------------------------------ + OP_STRB_P_LSL_IMM_OFF_PREIND, //011 1111 0 0000 + OP_UND, + OP_STRB_P_LSR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_P_ASR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_P_ROR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_P_LSL_IMM_OFF_PREIND, + OP_UND, + OP_STRB_P_LSR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_P_ASR_IMM_OFF_PREIND, + OP_UND, + OP_STRB_P_ROR_IMM_OFF_PREIND, + OP_UND, + + OP_LDRB_P_LSL_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_P_LSR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_P_ASR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_P_ROR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_P_LSL_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_P_LSR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_P_ASR_IMM_OFF_PREIND, + OP_UND, + OP_LDRB_P_ROR_IMM_OFF_PREIND, + OP_UND, //011 1111 1 1111 +//------------------------------------------ + OP_STMDA, //100 0000 0 0000 + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + OP_STMDA, + + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, + OP_LDMDA, +//------------------------------------------ + OP_STMDA_W, //100 0001 0 0000 + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + OP_STMDA_W, + + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, + OP_LDMDA_W, +//------------------------------------------ + OP_STMDA2, //100 0010 0 0000 + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + OP_STMDA2, + + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, + OP_LDMDA2, +//------------------------------------------ + OP_STMDA2_W, //100 0011 0 0000 + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + OP_STMDA2_W, + + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, + OP_LDMDA2_W, +//------------------------------------------ + OP_STMIA, //100 0100 0 0000 + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + OP_STMIA, + + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, + OP_LDMIA, +//------------------------------------------ + OP_STMIA_W, //100 0101 0 0000 + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + OP_STMIA_W, + + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, + OP_LDMIA_W, +//------------------------------------------ + OP_STMIA2, //100 0110 0 0000 + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + OP_STMIA2, + + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, + OP_LDMIA2, +//------------------------------------------ + OP_STMIA2_W, //100 0111 0 0000 + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + OP_STMIA2_W, + + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, + OP_LDMIA2_W, +//------------------------------------------ + OP_STMDB, //100 1000 0 0000 + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + OP_STMDB, + + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, + OP_LDMDB, +//------------------------------------------ + OP_STMDB_W, //100 1001 0 0000 + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + OP_STMDB_W, + + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, + OP_LDMDB_W, +//------------------------------------------ + OP_STMDB2, //100 1010 0 0000 + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + OP_STMDB2, + + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, + OP_LDMDB2, +//------------------------------------------ + OP_STMDB2_W, //100 1011 0 0000 + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + OP_STMDB2_W, + + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, + OP_LDMDB2_W, +//------------------------------------------ + + + OP_STMIB, //100 1100 0 0000 + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + OP_STMIB, + + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, + OP_LDMIB, +//------------------------------------------ + OP_STMIB_W, //100 1101 0 0000 + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + OP_STMIB_W, + + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, + OP_LDMIB_W, +//------------------------------------------ + OP_STMIB2, //100 1110 0 0000 + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + OP_STMIB2, + + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, + OP_LDMIB2, +//------------------------------------------ + OP_STMIB2_W, //100 1111 0 0000 + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + OP_STMIB2_W, + + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, + OP_LDMIB2_W, +//------------------------------------------ + OP_B, //101 0000 0 0000 + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, +//------------------------------------------ + OP_B, //101 0001 0 0000 + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, +//------------------------------------------ + OP_B, //101 0010 0 0000 + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, +//------------------------------------------ + OP_B, //101 0011 0 0000 + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, +//------------------------------------------ + OP_B, //101 0100 0 0000 + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, +//------------------------------------------ + OP_B, //101 0101 0 0000 + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, +//------------------------------------------ + OP_B, //101 0110 0 0000 + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, +//------------------------------------------ + OP_B, //101 0111 0 0000 + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, + OP_B, +//------------------------------------------ + OP_BL, //101 1000 0 0000 + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, +//------------------------------------------ + OP_BL, //101 1001 0 0000 + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, +//------------------------------------------ + OP_BL, //101 1010 0 0000 + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, +//------------------------------------------ + OP_BL, //101 1011 0 0000 + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, +//------------------------------------------ + OP_BL, //101 1100 0 0000 + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, +//------------------------------------------ + OP_BL, //101 1101 0 0000 + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, +//------------------------------------------ + OP_BL, //101 1110 0 0000 + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, +//------------------------------------------ + OP_BL, //101 1111 0 0000 + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, + OP_BL, +//------------------------------------------ + OP_STC_OPTION, //110 0000 0 0000 + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, +//------------------------------------------ + OP_STC_M_POSTIND, //110 0001 0 0000 + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, +//------------------------------------------ + OP_STC_OPTION, //110 0010 0 0000 + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, +//------------------------------------------ + OP_STC_M_POSTIND, //110 0011 0 0000 + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + OP_STC_M_POSTIND, + + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, + OP_LDC_M_POSTIND, +//------------------------------------------ + OP_STC_OPTION, //110 0100 0 0000 + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, +//------------------------------------------ + OP_STC_P_POSTIND, //110 0101 0 0000 + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, +//------------------------------------------ + OP_STC_OPTION, //110 0110 0 0000 + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + OP_STC_OPTION, + + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, + OP_LDC_OPTION, +//------------------------------------------ + OP_STC_P_POSTIND, //110 0111 0 0000 + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + OP_STC_P_POSTIND, + + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, + OP_LDC_P_POSTIND, +//------------------------------------------ + OP_STC_M_IMM_OFF, //110 1000 0 0000 + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, +//------------------------------------------ + OP_STC_M_PREIND, //110 1001 0 0000 + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, +//------------------------------------------ + OP_STC_M_IMM_OFF, //110 1010 0 0000 + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + OP_STC_M_IMM_OFF, + + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, + OP_LDC_M_IMM_OFF, +//------------------------------------------ + OP_STC_M_PREIND, //110 1011 0 0000 + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + OP_STC_M_PREIND, + + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, + OP_LDC_M_PREIND, +//------------------------------------------ + OP_STC_P_IMM_OFF, //110 1100 0 0000 + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, +//------------------------------------------ + OP_STC_P_PREIND, //110 1101 0 0000 + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, +//------------------------------------------ + OP_STC_P_IMM_OFF, //110 1110 0 0000 + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + OP_STC_P_IMM_OFF, + + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, + OP_LDC_P_IMM_OFF, +//------------------------------------------ + OP_STC_P_PREIND, //110 1111 0 0000 + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + OP_STC_P_PREIND, + + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, + OP_LDC_P_PREIND, +//------------------------------------------ + OP_CDP, //111 0000 0 0000 + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, +//--------------------------------------------- + OP_CDP, //111 0001 0 0000 + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, +//--------------------------------------------- + OP_CDP, //111 0010 0 0000 + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, +//--------------------------------------------- + OP_CDP, //111 0011 0 0000 + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, +//--------------------------------------------- + OP_CDP, //111 0100 0 0000 + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, +//--------------------------------------------- + OP_CDP, //111 0101 0 0000 + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, +//--------------------------------------------- + OP_CDP, //111 0110 0 0000 + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, +//--------------------------------------------- + OP_CDP, //111 0111 0 0000 + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + OP_CDP, + OP_MCR, + + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, + OP_CDP, + OP_MRC, +//--------------------------------------------- + OP_SWI, //111 1000 0 0000 + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, + OP_SWI, +}; + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/matrix.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/matrix.c new file mode 100755 index 000000000..555d62b15 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/matrix.c @@ -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 +#include +#include +#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); +} diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/matrix.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/matrix.h new file mode 100755 index 000000000..05c0786e2 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/matrix.h @@ -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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mc.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mc.c new file mode 100755 index 000000000..756a92c8d --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mc.c @@ -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 +#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; +} + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mc.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mc.h new file mode 100755 index 000000000..f78b7c39f --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mc.h @@ -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 +#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__*/ + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mem.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mem.h new file mode 100755 index 000000000..72060f1f5 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/mem.h @@ -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 +#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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/registers.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/registers.h new file mode 100755 index 000000000..f9060214d --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/registers.h @@ -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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/spu_exports.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/spu_exports.h new file mode 100755 index 000000000..770b9132f --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/spu_exports.h @@ -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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/state.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/state.c new file mode 100644 index 000000000..a113c45c1 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/state.c @@ -0,0 +1,766 @@ +// +// state.c +// vio2sf +// +// Created by Christopher Snowhill on 10/13/13. +// Copyright (c) 2013 Christopher Snowhill. All rights reserved. +// + +#include + +#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; iinitial_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; iinitial_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 +} diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/state.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/state.h new file mode 100644 index 000000000..756227e82 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/state.h @@ -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 diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_instructions.c b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_instructions.c new file mode 100755 index 000000000..80d5f0b25 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_instructions.c @@ -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" diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_instructions.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_instructions.h new file mode 100755 index 000000000..27088a6e3 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_instructions.h @@ -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 + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_tabdef.inc b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_tabdef.inc new file mode 100755 index 000000000..1a9c53b03 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/thumb_tabdef.inc @@ -0,0 +1,1111 @@ +/* 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 +*/ + +TYPE_RETOUR (* CALLTYPE NOM_THUMB_TAB[1024])(PARAMETRES)={ + OP_LSL_0, //00 0000 0000 + OP_LSL, //00 0000 0001 + OP_LSL, //00 0000 0010 + OP_LSL, //00 0000 0011 + OP_LSL, //00 0000 0100 + OP_LSL, //00 0000 0101 + OP_LSL, //00 0000 0110 + OP_LSL, //00 0000 0111 + OP_LSL, //00 0000 1000 + OP_LSL, //00 0000 1001 + OP_LSL, //00 0000 1010 + OP_LSL, //00 0000 1011 + OP_LSL, //00 0000 1100 + OP_LSL, //00 0000 1101 + OP_LSL, //00 0000 1110 + OP_LSL, //00 0000 1111 + + OP_LSL, //00 0001 0000 + OP_LSL, //00 0001 0001 + OP_LSL, //00 0001 0010 + OP_LSL, //00 0001 0011 + OP_LSL, //00 0001 0100 + OP_LSL, //00 0001 0101 + OP_LSL, //00 0001 0110 + OP_LSL, //00 0001 0111 + OP_LSL, //00 0001 1000 + OP_LSL, //00 0001 1001 + OP_LSL, //00 0001 1010 + OP_LSL, //00 0001 1011 + OP_LSL, //00 0001 1100 + OP_LSL, //00 0001 1101 + OP_LSL, //00 0001 1110 + OP_LSL, //00 0001 1111 + + OP_LSR_0, //00 0010 0000 + OP_LSR, //00 0010 0001 + OP_LSR, //00 0010 0010 + OP_LSR, //00 0010 0011 + OP_LSR, //00 0010 0100 + OP_LSR, //00 0010 0101 + OP_LSR, //00 0010 0110 + OP_LSR, //00 0010 0111 + OP_LSR, //00 0010 1000 + OP_LSR, //00 0010 1001 + OP_LSR, //00 0010 1010 + OP_LSR, //00 0010 1011 + OP_LSR, //00 0010 1100 + OP_LSR, //00 0010 1101 + OP_LSR, //00 0010 1110 + OP_LSR, //00 0010 1111 + + OP_LSR, //00 0011 0000 + OP_LSR, //00 0011 0001 + OP_LSR, //00 0011 0010 + OP_LSR, //00 0011 0011 + OP_LSR, //00 0011 0100 + OP_LSR, //00 0011 0101 + OP_LSR, //00 0011 0110 + OP_LSR, //00 0011 0111 + OP_LSR, //00 0011 1000 + OP_LSR, //00 0011 1001 + OP_LSR, //00 0011 1010 + OP_LSR, //00 0011 1011 + OP_LSR, //00 0011 1100 + OP_LSR, //00 0011 1101 + OP_LSR, //00 0011 1110 + OP_LSR, //00 0011 1111 + + OP_ASR_0, //00 0100 0000 + OP_ASR, //00 0100 0001 + OP_ASR, //00 0100 0010 + OP_ASR, //00 0100 0011 + OP_ASR, //00 0100 0100 + OP_ASR, //00 0100 0101 + OP_ASR, //00 0100 0110 + OP_ASR, //00 0100 0111 + OP_ASR, //00 0100 1000 + OP_ASR, //00 0100 1001 + OP_ASR, //00 0100 1010 + OP_ASR, //00 0100 1011 + OP_ASR, //00 0100 1100 + OP_ASR, //00 0100 1101 + OP_ASR, //00 0100 1110 + OP_ASR, //00 0100 1111 + + OP_ASR, //00 0101 0000 + OP_ASR, //00 0101 0001 + OP_ASR, //00 0101 0010 + OP_ASR, //00 0101 0011 + OP_ASR, //00 0101 0100 + OP_ASR, //00 0101 0101 + OP_ASR, //00 0101 0110 + OP_ASR, //00 0101 0111 + OP_ASR, //00 0101 1000 + OP_ASR, //00 0101 1001 + OP_ASR, //00 0101 1010 + OP_ASR, //00 0101 1011 + OP_ASR, //00 0101 1100 + OP_ASR, //00 0101 1101 + OP_ASR, //00 0101 1110 + OP_ASR, //00 0101 1111 + + OP_ADD_REG, //00 0110 0000 + OP_ADD_REG, //00 0110 0001 + OP_ADD_REG, //00 0110 0010 + OP_ADD_REG, //00 0110 0011 + OP_ADD_REG, //00 0110 0100 + OP_ADD_REG, //00 0110 0101 + OP_ADD_REG, //00 0110 0110 + OP_ADD_REG, //00 0110 0111 + OP_SUB_REG, //00 0110 1000 + OP_SUB_REG, //00 0110 1001 + OP_SUB_REG, //00 0110 1010 + OP_SUB_REG, //00 0110 1011 + OP_SUB_REG, //00 0110 1100 + OP_SUB_REG, //00 0110 1101 + OP_SUB_REG, //00 0110 1110 + OP_SUB_REG, //00 0110 1111 + + OP_ADD_IMM3, //00 0111 0000 + OP_ADD_IMM3, //00 0111 0001 + OP_ADD_IMM3, //00 0111 0010 + OP_ADD_IMM3, //00 0111 0011 + OP_ADD_IMM3, //00 0111 0100 + OP_ADD_IMM3, //00 0111 0101 + OP_ADD_IMM3, //00 0111 0110 + OP_ADD_IMM3, //00 0111 0111 + OP_SUB_IMM3, //00 0111 1000 + OP_SUB_IMM3, //00 0111 1001 + OP_SUB_IMM3, //00 0111 1010 + OP_SUB_IMM3, //00 0111 1011 + OP_SUB_IMM3, //00 0111 1100 + OP_SUB_IMM3, //00 0111 1101 + OP_SUB_IMM3, //00 0111 1110 + OP_SUB_IMM3, //00 0111 1111 + + OP_MOV_IMM8, //00 1000 0000 + OP_MOV_IMM8, //00 1000 0001 + OP_MOV_IMM8, //00 1000 0010 + OP_MOV_IMM8, //00 1000 0011 + OP_MOV_IMM8, //00 1000 0100 + OP_MOV_IMM8, //00 1000 0101 + OP_MOV_IMM8, //00 1000 0110 + OP_MOV_IMM8, //00 1000 0111 + OP_MOV_IMM8, //00 1000 1000 + OP_MOV_IMM8, //00 1000 1001 + OP_MOV_IMM8, //00 1000 1010 + OP_MOV_IMM8, //00 1000 1011 + OP_MOV_IMM8, //00 1000 1100 + OP_MOV_IMM8, //00 1000 1101 + OP_MOV_IMM8, //00 1000 1110 + OP_MOV_IMM8, //00 1000 1111 + + OP_MOV_IMM8, //00 1001 0000 + OP_MOV_IMM8, //00 1001 0001 + OP_MOV_IMM8, //00 1001 0010 + OP_MOV_IMM8, //00 1001 0011 + OP_MOV_IMM8, //00 1001 0100 + OP_MOV_IMM8, //00 1001 0101 + OP_MOV_IMM8, //00 1001 0110 + OP_MOV_IMM8, //00 1001 0111 + OP_MOV_IMM8, //00 1001 1000 + OP_MOV_IMM8, //00 1001 1001 + OP_MOV_IMM8, //00 1001 1010 + OP_MOV_IMM8, //00 1001 1011 + OP_MOV_IMM8, //00 1001 1100 + OP_MOV_IMM8, //00 1001 1101 + OP_MOV_IMM8, //00 1001 1110 + OP_MOV_IMM8, //00 1001 1111 + + OP_CMP_IMM8, //00 1010 0000 + OP_CMP_IMM8, //00 1010 0001 + OP_CMP_IMM8, //00 1010 0010 + OP_CMP_IMM8, //00 1010 0011 + OP_CMP_IMM8, //00 1010 0100 + OP_CMP_IMM8, //00 1010 0101 + OP_CMP_IMM8, //00 1010 0110 + OP_CMP_IMM8, //00 1010 0111 + OP_CMP_IMM8, //00 1010 1000 + OP_CMP_IMM8, //00 1010 1001 + OP_CMP_IMM8, //00 1010 1010 + OP_CMP_IMM8, //00 1010 1011 + OP_CMP_IMM8, //00 1010 1100 + OP_CMP_IMM8, //00 1010 1101 + OP_CMP_IMM8, //00 1010 1110 + OP_CMP_IMM8, //00 1010 1111 + + OP_CMP_IMM8, //00 1011 0000 + OP_CMP_IMM8, //00 1011 0001 + OP_CMP_IMM8, //00 1011 0010 + OP_CMP_IMM8, //00 1011 0011 + OP_CMP_IMM8, //00 1011 0100 + OP_CMP_IMM8, //00 1011 0101 + OP_CMP_IMM8, //00 1011 0110 + OP_CMP_IMM8, //00 1011 0111 + OP_CMP_IMM8, //00 1011 1000 + OP_CMP_IMM8, //00 1011 1001 + OP_CMP_IMM8, //00 1011 1010 + OP_CMP_IMM8, //00 1011 1011 + OP_CMP_IMM8, //00 1011 1100 + OP_CMP_IMM8, //00 1011 1101 + OP_CMP_IMM8, //00 1011 1110 + OP_CMP_IMM8, //00 1011 1111 + + OP_ADD_IMM8, //00 1100 0000 + OP_ADD_IMM8, //00 1100 0001 + OP_ADD_IMM8, //00 1100 0010 + OP_ADD_IMM8, //00 1100 0011 + OP_ADD_IMM8, //00 1100 0100 + OP_ADD_IMM8, //00 1100 0101 + OP_ADD_IMM8, //00 1100 0110 + OP_ADD_IMM8, //00 1100 0111 + OP_ADD_IMM8, //00 1100 1000 + OP_ADD_IMM8, //00 1100 1001 + OP_ADD_IMM8, //00 1100 1010 + OP_ADD_IMM8, //00 1100 1011 + OP_ADD_IMM8, //00 1100 1100 + OP_ADD_IMM8, //00 1100 1101 + OP_ADD_IMM8, //00 1100 1110 + OP_ADD_IMM8, //00 1100 1111 + + OP_ADD_IMM8, //00 1101 0000 + OP_ADD_IMM8, //00 1101 0001 + OP_ADD_IMM8, //00 1101 0010 + OP_ADD_IMM8, //00 1101 0011 + OP_ADD_IMM8, //00 1101 0100 + OP_ADD_IMM8, //00 1101 0101 + OP_ADD_IMM8, //00 1101 0110 + OP_ADD_IMM8, //00 1101 0111 + OP_ADD_IMM8, //00 1101 1000 + OP_ADD_IMM8, //00 1101 1001 + OP_ADD_IMM8, //00 1101 1010 + OP_ADD_IMM8, //00 1101 1011 + OP_ADD_IMM8, //00 1101 1100 + OP_ADD_IMM8, //00 1101 1101 + OP_ADD_IMM8, //00 1101 1110 + OP_ADD_IMM8, //00 1101 1111 + + OP_SUB_IMM8, //00 1110 0000 + OP_SUB_IMM8, //00 1110 0001 + OP_SUB_IMM8, //00 1110 0010 + OP_SUB_IMM8, //00 1110 0011 + OP_SUB_IMM8, //00 1110 0100 + OP_SUB_IMM8, //00 1110 0101 + OP_SUB_IMM8, //00 1110 0110 + OP_SUB_IMM8, //00 1110 0111 + OP_SUB_IMM8, //00 1110 1000 + OP_SUB_IMM8, //00 1110 1001 + OP_SUB_IMM8, //00 1110 1010 + OP_SUB_IMM8, //00 1110 1011 + OP_SUB_IMM8, //00 1110 1100 + OP_SUB_IMM8, //00 1110 1101 + OP_SUB_IMM8, //00 1110 1110 + OP_SUB_IMM8, //00 1110 1111 + + OP_SUB_IMM8, //00 1111 0000 + OP_SUB_IMM8, //00 1111 0001 + OP_SUB_IMM8, //00 1111 0010 + OP_SUB_IMM8, //00 1111 0011 + OP_SUB_IMM8, //00 1111 0100 + OP_SUB_IMM8, //00 1111 0101 + OP_SUB_IMM8, //00 1111 0110 + OP_SUB_IMM8, //00 1111 0111 + OP_SUB_IMM8, //00 1111 1000 + OP_SUB_IMM8, //00 1111 1001 + OP_SUB_IMM8, //00 1111 1010 + OP_SUB_IMM8, //00 1111 1011 + OP_SUB_IMM8, //00 1111 1100 + OP_SUB_IMM8, //00 1111 1101 + OP_SUB_IMM8, //00 1111 1110 + OP_SUB_IMM8, //00 1111 1111 + + OP_AND, //01 0000 0000 + OP_EOR, //01 0000 0001 + OP_LSL_REG, //01 0000 0010 + OP_LSR_REG, //01 0000 0011 + OP_ASR_REG, //01 0000 0100 + OP_ADC_REG, //01 0000 0101 + OP_SBC_REG, //01 0000 0110 + OP_ROR_REG, //01 0000 0111 + OP_TST, //01 0000 1000 + OP_NEG, //01 0000 1001 + OP_CMP, //01 0000 1010 + OP_CMN, //01 0000 1011 + OP_ORR, //01 0000 1100 + OP_MUL_REG, //01 0000 1101 + OP_BIC, //01 0000 1110 + OP_MVN, //01 0000 1111 + + OP_ADD_SPE, //01 0001 0000 + OP_ADD_SPE, //01 0001 0001 + OP_ADD_SPE, //01 0001 0010 + OP_ADD_SPE, //01 0001 0011 + OP_CMP_SPE, //01 0001 0100 + OP_CMP_SPE, //01 0001 0101 + OP_CMP_SPE, //01 0001 0110 + OP_CMP_SPE, //01 0001 0111 + OP_MOV_SPE, //01 0001 1000 + OP_MOV_SPE, //01 0001 1001 + OP_MOV_SPE, //01 0001 1010 + OP_MOV_SPE, //01 0001 1011 + OP_BX_THUMB, //01 0001 1100 + OP_BX_THUMB, //01 0001 1101 + OP_BLX_THUMB, //01 0001 1110 + OP_BLX_THUMB, //01 0001 1111 + + OP_LDR_PCREL, //01 0010 0000 + OP_LDR_PCREL, //01 0010 0001 + OP_LDR_PCREL, //01 0010 0010 + OP_LDR_PCREL, //01 0010 0011 + OP_LDR_PCREL, //01 0010 0100 + OP_LDR_PCREL, //01 0010 0101 + OP_LDR_PCREL, //01 0010 0110 + OP_LDR_PCREL, //01 0010 0111 + OP_LDR_PCREL, //01 0010 1000 + OP_LDR_PCREL, //01 0010 1001 + OP_LDR_PCREL, //01 0010 1010 + OP_LDR_PCREL, //01 0010 1011 + OP_LDR_PCREL, //01 0010 1100 + OP_LDR_PCREL, //01 0010 1101 + OP_LDR_PCREL, //01 0010 1110 + OP_LDR_PCREL, //01 0010 1111 + + OP_LDR_PCREL, //01 0011 0000 + OP_LDR_PCREL, //01 0011 0001 + OP_LDR_PCREL, //01 0011 0010 + OP_LDR_PCREL, //01 0011 0011 + OP_LDR_PCREL, //01 0011 0100 + OP_LDR_PCREL, //01 0011 0101 + OP_LDR_PCREL, //01 0011 0110 + OP_LDR_PCREL, //01 0011 0111 + OP_LDR_PCREL, //01 0011 1000 + OP_LDR_PCREL, //01 0011 1001 + OP_LDR_PCREL, //01 0011 1010 + OP_LDR_PCREL, //01 0011 1011 + OP_LDR_PCREL, //01 0011 1100 + OP_LDR_PCREL, //01 0011 1101 + OP_LDR_PCREL, //01 0011 1110 + OP_LDR_PCREL, //01 0011 1111 + + OP_STR_REG_OFF, //01 0100 0000 + OP_STR_REG_OFF, //01 0100 0001 + OP_STR_REG_OFF, //01 0100 0010 + OP_STR_REG_OFF, //01 0100 0011 + OP_STR_REG_OFF, //01 0100 0100 + OP_STR_REG_OFF, //01 0100 0101 + OP_STR_REG_OFF, //01 0100 0110 + OP_STR_REG_OFF, //01 0100 0111 + OP_STRH_REG_OFF, //01 0100 1000 + OP_STRH_REG_OFF, //01 0100 1001 + OP_STRH_REG_OFF, //01 0100 1010 + OP_STRH_REG_OFF, //01 0100 1011 + OP_STRH_REG_OFF, //01 0100 1100 + OP_STRH_REG_OFF, //01 0100 1101 + OP_STRH_REG_OFF, //01 0100 1110 + OP_STRH_REG_OFF, //01 0100 1111 + + OP_STRB_REG_OFF, //01 0101 0000 + OP_STRB_REG_OFF, //01 0101 0001 + OP_STRB_REG_OFF, //01 0101 0010 + OP_STRB_REG_OFF, //01 0101 0011 + OP_STRB_REG_OFF, //01 0101 0100 + OP_STRB_REG_OFF, //01 0101 0101 + OP_STRB_REG_OFF, //01 0101 0110 + OP_STRB_REG_OFF, //01 0101 0111 + OP_LDRSB_REG_OFF, //01 0101 1000 + OP_LDRSB_REG_OFF, //01 0101 1001 + OP_LDRSB_REG_OFF, //01 0101 1010 + OP_LDRSB_REG_OFF, //01 0101 1011 + OP_LDRSB_REG_OFF, //01 0101 1100 + OP_LDRSB_REG_OFF, //01 0101 1101 + OP_LDRSB_REG_OFF, //01 0101 1110 + OP_LDRSB_REG_OFF, //01 0101 1111 + + OP_LDR_REG_OFF, //01 0110 0000 + OP_LDR_REG_OFF, //01 0110 0001 + OP_LDR_REG_OFF, //01 0110 0010 + OP_LDR_REG_OFF, //01 0110 0011 + OP_LDR_REG_OFF, //01 0110 0100 + OP_LDR_REG_OFF, //01 0110 0101 + OP_LDR_REG_OFF, //01 0110 0110 + OP_LDR_REG_OFF, //01 0110 0111 + OP_LDRH_REG_OFF, //01 0110 1000 + OP_LDRH_REG_OFF, //01 0110 1001 + OP_LDRH_REG_OFF, //01 0110 1010 + OP_LDRH_REG_OFF, //01 0110 1011 + OP_LDRH_REG_OFF, //01 0110 1100 + OP_LDRH_REG_OFF, //01 0110 1101 + OP_LDRH_REG_OFF, //01 0110 1110 + OP_LDRH_REG_OFF, //01 0110 1111 + + OP_LDRB_REG_OFF, //01 0111 0000 + OP_LDRB_REG_OFF, //01 0111 0001 + OP_LDRB_REG_OFF, //01 0111 0010 + OP_LDRB_REG_OFF, //01 0111 0011 + OP_LDRB_REG_OFF, //01 0111 0100 + OP_LDRB_REG_OFF, //01 0111 0101 + OP_LDRB_REG_OFF, //01 0111 0110 + OP_LDRB_REG_OFF, //01 0111 0111 + OP_LDRSH_REG_OFF, //01 0111 1000 + OP_LDRSH_REG_OFF, //01 0111 1001 + OP_LDRSH_REG_OFF, //01 0111 1010 + OP_LDRSH_REG_OFF, //01 0111 1011 + OP_LDRSH_REG_OFF, //01 0111 1100 + OP_LDRSH_REG_OFF, //01 0111 1101 + OP_LDRSH_REG_OFF, //01 0111 1110 + OP_LDRSH_REG_OFF, //01 0111 1111 + + OP_STR_IMM_OFF, //01 1000 0000 + OP_STR_IMM_OFF, //01 1000 0001 + OP_STR_IMM_OFF, //01 1000 0010 + OP_STR_IMM_OFF, //01 1000 0011 + OP_STR_IMM_OFF, //01 1000 0100 + OP_STR_IMM_OFF, //01 1000 0101 + OP_STR_IMM_OFF, //01 1000 0110 + OP_STR_IMM_OFF, //01 1000 0111 + OP_STR_IMM_OFF, //01 1000 1000 + OP_STR_IMM_OFF, //01 1000 1001 + OP_STR_IMM_OFF, //01 1000 1010 + OP_STR_IMM_OFF, //01 1000 1011 + OP_STR_IMM_OFF, //01 1000 1100 + OP_STR_IMM_OFF, //01 1000 1101 + OP_STR_IMM_OFF, //01 1000 1110 + OP_STR_IMM_OFF, //01 1000 1111 + + OP_STR_IMM_OFF, //01 1001 0000 + OP_STR_IMM_OFF, //01 1001 0001 + OP_STR_IMM_OFF, //01 1001 0010 + OP_STR_IMM_OFF, //01 1001 0011 + OP_STR_IMM_OFF, //01 1001 0100 + OP_STR_IMM_OFF, //01 1001 0101 + OP_STR_IMM_OFF, //01 1001 0110 + OP_STR_IMM_OFF, //01 1001 0111 + OP_STR_IMM_OFF, //01 1001 1000 + OP_STR_IMM_OFF, //01 1001 1001 + OP_STR_IMM_OFF, //01 1001 1010 + OP_STR_IMM_OFF, //01 1001 1011 + OP_STR_IMM_OFF, //01 1001 1100 + OP_STR_IMM_OFF, //01 1001 1101 + OP_STR_IMM_OFF, //01 1001 1110 + OP_STR_IMM_OFF, //01 1001 1111 + + OP_LDR_IMM_OFF, //01 1010 0000 + OP_LDR_IMM_OFF, //01 1010 0001 + OP_LDR_IMM_OFF, //01 1010 0010 + OP_LDR_IMM_OFF, //01 1010 0011 + OP_LDR_IMM_OFF, //01 1010 0100 + OP_LDR_IMM_OFF, //01 1010 0101 + OP_LDR_IMM_OFF, //01 1010 0110 + OP_LDR_IMM_OFF, //01 1010 0111 + OP_LDR_IMM_OFF, //01 1010 1000 + OP_LDR_IMM_OFF, //01 1010 1001 + OP_LDR_IMM_OFF, //01 1010 1010 + OP_LDR_IMM_OFF, //01 1010 1011 + OP_LDR_IMM_OFF, //01 1010 1100 + OP_LDR_IMM_OFF, //01 1010 1101 + OP_LDR_IMM_OFF, //01 1010 1110 + OP_LDR_IMM_OFF, //01 1010 1111 + + OP_LDR_IMM_OFF, //01 1011 0000 + OP_LDR_IMM_OFF, //01 1011 0001 + OP_LDR_IMM_OFF, //01 1011 0010 + OP_LDR_IMM_OFF, //01 1011 0011 + OP_LDR_IMM_OFF, //01 1011 0100 + OP_LDR_IMM_OFF, //01 1011 0101 + OP_LDR_IMM_OFF, //01 1011 0110 + OP_LDR_IMM_OFF, //01 1011 0111 + OP_LDR_IMM_OFF, //01 1011 1000 + OP_LDR_IMM_OFF, //01 1011 1001 + OP_LDR_IMM_OFF, //01 1011 1010 + OP_LDR_IMM_OFF, //01 1011 1011 + OP_LDR_IMM_OFF, //01 1011 1100 + OP_LDR_IMM_OFF, //01 1011 1101 + OP_LDR_IMM_OFF, //01 1011 1110 + OP_LDR_IMM_OFF, //01 1011 1111 + + OP_STRB_IMM_OFF, //01 1100 0000 + OP_STRB_IMM_OFF, //01 1100 0001 + OP_STRB_IMM_OFF, //01 1100 0010 + OP_STRB_IMM_OFF, //01 1100 0011 + OP_STRB_IMM_OFF, //01 1100 0100 + OP_STRB_IMM_OFF, //01 1100 0101 + OP_STRB_IMM_OFF, //01 1100 0110 + OP_STRB_IMM_OFF, //01 1100 0111 + OP_STRB_IMM_OFF, //01 1100 1000 + OP_STRB_IMM_OFF, //01 1100 1001 + OP_STRB_IMM_OFF, //01 1100 1010 + OP_STRB_IMM_OFF, //01 1100 1011 + OP_STRB_IMM_OFF, //01 1100 1100 + OP_STRB_IMM_OFF, //01 1100 1101 + OP_STRB_IMM_OFF, //01 1100 1110 + OP_STRB_IMM_OFF, //01 1100 1111 + + OP_STRB_IMM_OFF, //01 1101 0000 + OP_STRB_IMM_OFF, //01 1101 0001 + OP_STRB_IMM_OFF, //01 1101 0010 + OP_STRB_IMM_OFF, //01 1101 0011 + OP_STRB_IMM_OFF, //01 1101 0100 + OP_STRB_IMM_OFF, //01 1101 0101 + OP_STRB_IMM_OFF, //01 1101 0110 + OP_STRB_IMM_OFF, //01 1101 0111 + OP_STRB_IMM_OFF, //01 1101 1000 + OP_STRB_IMM_OFF, //01 1101 1001 + OP_STRB_IMM_OFF, //01 1101 1010 + OP_STRB_IMM_OFF, //01 1101 1011 + OP_STRB_IMM_OFF, //01 1101 1100 + OP_STRB_IMM_OFF, //01 1101 1101 + OP_STRB_IMM_OFF, //01 1101 1110 + OP_STRB_IMM_OFF, //01 1101 1111 + + OP_LDRB_IMM_OFF, //01 1110 0000 + OP_LDRB_IMM_OFF, //01 1110 0001 + OP_LDRB_IMM_OFF, //01 1110 0010 + OP_LDRB_IMM_OFF, //01 1110 0011 + OP_LDRB_IMM_OFF, //01 1110 0100 + OP_LDRB_IMM_OFF, //01 1110 0101 + OP_LDRB_IMM_OFF, //01 1110 0110 + OP_LDRB_IMM_OFF, //01 1110 0111 + OP_LDRB_IMM_OFF, //01 1110 1000 + OP_LDRB_IMM_OFF, //01 1110 1001 + OP_LDRB_IMM_OFF, //01 1110 1010 + OP_LDRB_IMM_OFF, //01 1110 1011 + OP_LDRB_IMM_OFF, //01 1110 1100 + OP_LDRB_IMM_OFF, //01 1110 1101 + OP_LDRB_IMM_OFF, //01 1110 1110 + OP_LDRB_IMM_OFF, //01 1110 1111 + + OP_LDRB_IMM_OFF, //01 1111 0000 + OP_LDRB_IMM_OFF, //01 1111 0001 + OP_LDRB_IMM_OFF, //01 1111 0010 + OP_LDRB_IMM_OFF, //01 1111 0011 + OP_LDRB_IMM_OFF, //01 1111 0100 + OP_LDRB_IMM_OFF, //01 1111 0101 + OP_LDRB_IMM_OFF, //01 1111 0110 + OP_LDRB_IMM_OFF, //01 1111 0111 + OP_LDRB_IMM_OFF, //01 1111 1000 + OP_LDRB_IMM_OFF, //01 1111 1001 + OP_LDRB_IMM_OFF, //01 1111 1010 + OP_LDRB_IMM_OFF, //01 1111 1011 + OP_LDRB_IMM_OFF, //01 1111 1100 + OP_LDRB_IMM_OFF, //01 1111 1101 + OP_LDRB_IMM_OFF, //01 1111 1110 + OP_LDRB_IMM_OFF, //01 1111 1111 + + OP_STRH_IMM_OFF, //10 0000 0000 + OP_STRH_IMM_OFF, //10 0000 0001 + OP_STRH_IMM_OFF, //10 0000 0010 + OP_STRH_IMM_OFF, //10 0000 0011 + OP_STRH_IMM_OFF, //10 0000 0100 + OP_STRH_IMM_OFF, //10 0000 0101 + OP_STRH_IMM_OFF, //10 0000 0110 + OP_STRH_IMM_OFF, //10 0000 0111 + OP_STRH_IMM_OFF, //10 0000 1000 + OP_STRH_IMM_OFF, //10 0000 1001 + OP_STRH_IMM_OFF, //10 0000 1010 + OP_STRH_IMM_OFF, //10 0000 1011 + OP_STRH_IMM_OFF, //10 0000 1100 + OP_STRH_IMM_OFF, //10 0000 1101 + OP_STRH_IMM_OFF, //10 0000 1110 + OP_STRH_IMM_OFF, //10 0000 1111 + + OP_STRH_IMM_OFF, //10 0001 0000 + OP_STRH_IMM_OFF, //10 0001 0001 + OP_STRH_IMM_OFF, //10 0001 0010 + OP_STRH_IMM_OFF, //10 0001 0011 + OP_STRH_IMM_OFF, //10 0001 0100 + OP_STRH_IMM_OFF, //10 0001 0101 + OP_STRH_IMM_OFF, //10 0001 0110 + OP_STRH_IMM_OFF, //10 0001 0111 + OP_STRH_IMM_OFF, //10 0001 1000 + OP_STRH_IMM_OFF, //10 0001 1001 + OP_STRH_IMM_OFF, //10 0001 1010 + OP_STRH_IMM_OFF, //10 0001 1011 + OP_STRH_IMM_OFF, //10 0001 1100 + OP_STRH_IMM_OFF, //10 0001 1101 + OP_STRH_IMM_OFF, //10 0001 1110 + OP_STRH_IMM_OFF, //10 0001 1111 + + OP_LDRH_IMM_OFF, //10 0010 0000 + OP_LDRH_IMM_OFF, //10 0010 0001 + OP_LDRH_IMM_OFF, //10 0010 0010 + OP_LDRH_IMM_OFF, //10 0010 0011 + OP_LDRH_IMM_OFF, //10 0010 0100 + OP_LDRH_IMM_OFF, //10 0010 0101 + OP_LDRH_IMM_OFF, //10 0010 0110 + OP_LDRH_IMM_OFF, //10 0010 0111 + OP_LDRH_IMM_OFF, //10 0010 1000 + OP_LDRH_IMM_OFF, //10 0010 1001 + OP_LDRH_IMM_OFF, //10 0010 1010 + OP_LDRH_IMM_OFF, //10 0010 1011 + OP_LDRH_IMM_OFF, //10 0010 1100 + OP_LDRH_IMM_OFF, //10 0010 1101 + OP_LDRH_IMM_OFF, //10 0010 1110 + OP_LDRH_IMM_OFF, //10 0010 1111 + + OP_LDRH_IMM_OFF, //10 0011 0000 + OP_LDRH_IMM_OFF, //10 0011 0001 + OP_LDRH_IMM_OFF, //10 0011 0010 + OP_LDRH_IMM_OFF, //10 0011 0011 + OP_LDRH_IMM_OFF, //10 0011 0100 + OP_LDRH_IMM_OFF, //10 0011 0101 + OP_LDRH_IMM_OFF, //10 0011 0110 + OP_LDRH_IMM_OFF, //10 0011 0111 + OP_LDRH_IMM_OFF, //10 0011 1000 + OP_LDRH_IMM_OFF, //10 0011 1001 + OP_LDRH_IMM_OFF, //10 0011 1010 + OP_LDRH_IMM_OFF, //10 0011 1011 + OP_LDRH_IMM_OFF, //10 0011 1100 + OP_LDRH_IMM_OFF, //10 0011 1101 + OP_LDRH_IMM_OFF, //10 0011 1110 + OP_LDRH_IMM_OFF, //10 0011 1111 + + OP_STR_SPREL, //10 0100 0000 + OP_STR_SPREL, //10 0100 0001 + OP_STR_SPREL, //10 0100 0010 + OP_STR_SPREL, //10 0100 0011 + OP_STR_SPREL, //10 0100 0100 + OP_STR_SPREL, //10 0100 0101 + OP_STR_SPREL, //10 0100 0110 + OP_STR_SPREL, //10 0100 0111 + OP_STR_SPREL, //10 0100 1000 + OP_STR_SPREL, //10 0100 1001 + OP_STR_SPREL, //10 0100 1010 + OP_STR_SPREL, //10 0100 1011 + OP_STR_SPREL, //10 0100 1100 + OP_STR_SPREL, //10 0100 1101 + OP_STR_SPREL, //10 0100 1110 + OP_STR_SPREL, //10 0100 1111 + + OP_STR_SPREL, //10 0101 0000 + OP_STR_SPREL, //10 0101 0001 + OP_STR_SPREL, //10 0101 0010 + OP_STR_SPREL, //10 0101 0011 + OP_STR_SPREL, //10 0101 0100 + OP_STR_SPREL, //10 0101 0101 + OP_STR_SPREL, //10 0101 0110 + OP_STR_SPREL, //10 0101 0111 + OP_STR_SPREL, //10 0101 1000 + OP_STR_SPREL, //10 0101 1001 + OP_STR_SPREL, //10 0101 1010 + OP_STR_SPREL, //10 0101 1011 + OP_STR_SPREL, //10 0101 1100 + OP_STR_SPREL, //10 0101 1101 + OP_STR_SPREL, //10 0101 1110 + OP_STR_SPREL, //10 0101 1111 + + OP_LDR_SPREL, //10 0110 0000 + OP_LDR_SPREL, //10 0110 0001 + OP_LDR_SPREL, //10 0110 0010 + OP_LDR_SPREL, //10 0110 0011 + OP_LDR_SPREL, //10 0110 0100 + OP_LDR_SPREL, //10 0110 0101 + OP_LDR_SPREL, //10 0110 0110 + OP_LDR_SPREL, //10 0110 0111 + OP_LDR_SPREL, //10 0110 1000 + OP_LDR_SPREL, //10 0110 1001 + OP_LDR_SPREL, //10 0110 1010 + OP_LDR_SPREL, //10 0110 1011 + OP_LDR_SPREL, //10 0110 1100 + OP_LDR_SPREL, //10 0110 1101 + OP_LDR_SPREL, //10 0110 1110 + OP_LDR_SPREL, //10 0110 1111 + + OP_LDR_SPREL, //10 0111 0000 + OP_LDR_SPREL, //10 0111 0001 + OP_LDR_SPREL, //10 0111 0010 + OP_LDR_SPREL, //10 0111 0011 + OP_LDR_SPREL, //10 0111 0100 + OP_LDR_SPREL, //10 0111 0101 + OP_LDR_SPREL, //10 0111 0110 + OP_LDR_SPREL, //10 0111 0111 + OP_LDR_SPREL, //10 0111 1000 + OP_LDR_SPREL, //10 0111 1001 + OP_LDR_SPREL, //10 0111 1010 + OP_LDR_SPREL, //10 0111 1011 + OP_LDR_SPREL, //10 0111 1100 + OP_LDR_SPREL, //10 0111 1101 + OP_LDR_SPREL, //10 0111 1110 + OP_LDR_SPREL, //10 0111 1111 + + OP_ADD_2PC, //10 1000 0000 + OP_ADD_2PC, //10 1000 0001 + OP_ADD_2PC, //10 1000 0010 + OP_ADD_2PC, //10 1000 0011 + OP_ADD_2PC, //10 1000 0100 + OP_ADD_2PC, //10 1000 0101 + OP_ADD_2PC, //10 1000 0110 + OP_ADD_2PC, //10 1000 0111 + OP_ADD_2PC, //10 1000 1000 + OP_ADD_2PC, //10 1000 1001 + OP_ADD_2PC, //10 1000 1010 + OP_ADD_2PC, //10 1000 1011 + OP_ADD_2PC, //10 1000 1100 + OP_ADD_2PC, //10 1000 1101 + OP_ADD_2PC, //10 1000 1110 + OP_ADD_2PC, //10 1000 1111 + + OP_ADD_2PC, //10 1001 0000 + OP_ADD_2PC, //10 1001 0001 + OP_ADD_2PC, //10 1001 0010 + OP_ADD_2PC, //10 1001 0011 + OP_ADD_2PC, //10 1001 0100 + OP_ADD_2PC, //10 1001 0101 + OP_ADD_2PC, //10 1001 0110 + OP_ADD_2PC, //10 1001 0111 + OP_ADD_2PC, //10 1001 1000 + OP_ADD_2PC, //10 1001 1001 + OP_ADD_2PC, //10 1001 1010 + OP_ADD_2PC, //10 1001 1011 + OP_ADD_2PC, //10 1001 1100 + OP_ADD_2PC, //10 1001 1101 + OP_ADD_2PC, //10 1001 1110 + OP_ADD_2PC, //10 1001 1111 + + OP_ADD_2SP, //10 1010 0000 + OP_ADD_2SP, //10 1010 0001 + OP_ADD_2SP, //10 1010 0010 + OP_ADD_2SP, //10 1010 0011 + OP_ADD_2SP, //10 1010 0100 + OP_ADD_2SP, //10 1010 0101 + OP_ADD_2SP, //10 1010 0110 + OP_ADD_2SP, //10 1010 0111 + OP_ADD_2SP, //10 1010 1000 + OP_ADD_2SP, //10 1010 1001 + OP_ADD_2SP, //10 1010 1010 + OP_ADD_2SP, //10 1010 1011 + OP_ADD_2SP, //10 1010 1100 + OP_ADD_2SP, //10 1010 1101 + OP_ADD_2SP, //10 1010 1110 + OP_ADD_2SP, //10 1010 1111 + + OP_ADD_2SP, //10 1011 0000 + OP_ADD_2SP, //10 1011 0001 + OP_ADD_2SP, //10 1011 0010 + OP_ADD_2SP, //10 1011 0011 + OP_ADD_2SP, //10 1011 0100 + OP_ADD_2SP, //10 1011 0101 + OP_ADD_2SP, //10 1011 0110 + OP_ADD_2SP, //10 1011 0111 + OP_ADD_2SP, //10 1011 1000 + OP_ADD_2SP, //10 1011 1001 + OP_ADD_2SP, //10 1011 1010 + OP_ADD_2SP, //10 1011 1011 + OP_ADD_2SP, //10 1011 1100 + OP_ADD_2SP, //10 1011 1101 + OP_ADD_2SP, //10 1011 1110 + OP_ADD_2SP, //10 1011 1111 + + OP_ADJUST_P_SP, //10 1100 0000 + OP_ADJUST_P_SP, //10 1100 0001 + OP_ADJUST_M_SP, //10 1100 0010 + OP_ADJUST_M_SP, //10 1100 0011 + OP_UND_THUMB, //10 1100 0100 + OP_UND_THUMB, //10 1100 0101 + OP_UND_THUMB, //10 1100 0110 + OP_UND_THUMB, //10 1100 0111 + OP_UND_THUMB, //10 1100 1000 + OP_UND_THUMB, //10 1100 1001 + OP_UND_THUMB, //10 1100 1010 + OP_UND_THUMB, //10 1100 1011 + OP_UND_THUMB, //10 1100 1100 + OP_UND_THUMB, //10 1100 1101 + OP_UND_THUMB, //10 1100 1110 + OP_UND_THUMB, //10 1100 1111 + + OP_PUSH, //10 1101 0000 + OP_PUSH, //10 1101 0001 + OP_PUSH, //10 1101 0010 + OP_PUSH, //10 1101 0011 + OP_PUSH_LR, //10 1101 0100 + OP_PUSH_LR, //10 1101 0101 + OP_PUSH_LR, //10 1101 0110 + OP_PUSH_LR, //10 1101 0111 + OP_UND_THUMB, //10 1101 1000 + OP_UND_THUMB, //10 1101 1001 + OP_UND_THUMB, //10 1101 1010 + OP_UND_THUMB, //10 1101 1011 + OP_UND_THUMB, //10 1101 1100 + OP_UND_THUMB, //10 1101 1101 + OP_UND_THUMB, //10 1101 1110 + OP_UND_THUMB, //10 1101 1111 + + OP_UND_THUMB, //10 1110 0000 + OP_UND_THUMB, //10 1110 0001 + OP_UND_THUMB, //10 1110 0010 + OP_UND_THUMB, //10 1110 0011 + OP_UND_THUMB, //10 1110 0100 + OP_UND_THUMB, //10 1110 0101 + OP_UND_THUMB, //10 1110 0110 + OP_UND_THUMB, //10 1110 0111 + OP_UND_THUMB, //10 1110 1000 + OP_UND_THUMB, //10 1110 1001 + OP_UND_THUMB, //10 1110 1010 + OP_UND_THUMB, //10 1110 1011 + OP_UND_THUMB, //10 1110 1100 + OP_UND_THUMB, //10 1110 1101 + OP_UND_THUMB, //10 1110 1110 + OP_UND_THUMB, //10 1110 1111 + + OP_POP, //10 1111 0000 + OP_POP, //10 1111 0001 + OP_POP, //10 1111 0010 + OP_POP, //10 1111 0011 + OP_POP_PC, //10 1111 0100 + OP_POP_PC, //10 1111 0101 + OP_POP_PC, //10 1111 0110 + OP_POP_PC, //10 1111 0111 + OP_BKPT_THUMB, //10 1111 1000 + OP_BKPT_THUMB, //10 1111 1001 + OP_BKPT_THUMB, //10 1111 1010 + OP_BKPT_THUMB, //10 1111 1011 + OP_UND_THUMB, //10 1111 1100 + OP_UND_THUMB, //10 1111 1101 + OP_UND_THUMB, //10 1111 1110 + OP_UND_THUMB, //10 1111 1111 + + OP_STMIA_THUMB, //11 0000 0000 + OP_STMIA_THUMB, //11 0000 0001 + OP_STMIA_THUMB, //11 0000 0010 + OP_STMIA_THUMB, //11 0000 0011 + OP_STMIA_THUMB, //11 0000 0100 + OP_STMIA_THUMB, //11 0000 0101 + OP_STMIA_THUMB, //11 0000 0110 + OP_STMIA_THUMB, //11 0000 0111 + OP_STMIA_THUMB, //11 0000 1000 + OP_STMIA_THUMB, //11 0000 1001 + OP_STMIA_THUMB, //11 0000 1010 + OP_STMIA_THUMB, //11 0000 1011 + OP_STMIA_THUMB, //11 0000 1100 + OP_STMIA_THUMB, //11 0000 1101 + OP_STMIA_THUMB, //11 0000 1110 + OP_STMIA_THUMB, //11 0000 1111 + + OP_STMIA_THUMB, //11 0001 0000 + OP_STMIA_THUMB, //11 0001 0001 + OP_STMIA_THUMB, //11 0001 0010 + OP_STMIA_THUMB, //11 0001 0011 + OP_STMIA_THUMB, //11 0001 0100 + OP_STMIA_THUMB, //11 0001 0101 + OP_STMIA_THUMB, //11 0001 0110 + OP_STMIA_THUMB, //11 0001 0111 + OP_STMIA_THUMB, //11 0001 1000 + OP_STMIA_THUMB, //11 0001 1001 + OP_STMIA_THUMB, //11 0001 1010 + OP_STMIA_THUMB, //11 0001 1011 + OP_STMIA_THUMB, //11 0001 1100 + OP_STMIA_THUMB, //11 0001 1101 + OP_STMIA_THUMB, //11 0001 1110 + OP_STMIA_THUMB, //11 0001 1111 + + OP_LDMIA_THUMB, //11 0010 0000 + OP_LDMIA_THUMB, //11 0010 0001 + OP_LDMIA_THUMB, //11 0010 0010 + OP_LDMIA_THUMB, //11 0010 0011 + OP_LDMIA_THUMB, //11 0010 0100 + OP_LDMIA_THUMB, //11 0010 0101 + OP_LDMIA_THUMB, //11 0010 0110 + OP_LDMIA_THUMB, //11 0010 0111 + OP_LDMIA_THUMB, //11 0010 1000 + OP_LDMIA_THUMB, //11 0010 1001 + OP_LDMIA_THUMB, //11 0010 1010 + OP_LDMIA_THUMB, //11 0010 1011 + OP_LDMIA_THUMB, //11 0010 1100 + OP_LDMIA_THUMB, //11 0010 1101 + OP_LDMIA_THUMB, //11 0010 1110 + OP_LDMIA_THUMB, //11 0010 1111 + + OP_LDMIA_THUMB, //11 0011 0000 + OP_LDMIA_THUMB, //11 0011 0001 + OP_LDMIA_THUMB, //11 0011 0010 + OP_LDMIA_THUMB, //11 0011 0011 + OP_LDMIA_THUMB, //11 0011 0100 + OP_LDMIA_THUMB, //11 0011 0101 + OP_LDMIA_THUMB, //11 0011 0110 + OP_LDMIA_THUMB, //11 0011 0111 + OP_LDMIA_THUMB, //11 0011 1000 + OP_LDMIA_THUMB, //11 0011 1001 + OP_LDMIA_THUMB, //11 0011 1010 + OP_LDMIA_THUMB, //11 0011 1011 + OP_LDMIA_THUMB, //11 0011 1100 + OP_LDMIA_THUMB, //11 0011 1101 + OP_LDMIA_THUMB, //11 0011 1110 + OP_LDMIA_THUMB, //11 0011 1111 + + OP_B_COND, //11 0100 0000 + OP_B_COND, //11 0100 0001 + OP_B_COND, //11 0100 0010 + OP_B_COND, //11 0100 0011 + OP_B_COND, //11 0100 0100 + OP_B_COND, //11 0100 0101 + OP_B_COND, //11 0100 0110 + OP_B_COND, //11 0100 0111 + OP_B_COND, //11 0100 1000 + OP_B_COND, //11 0100 1001 + OP_B_COND, //11 0100 1010 + OP_B_COND, //11 0100 1011 + OP_B_COND, //11 0100 1100 + OP_B_COND, //11 0100 1101 + OP_B_COND, //11 0100 1110 + OP_B_COND, //11 0100 1111 + + OP_B_COND, //11 0101 0000 + OP_B_COND, //11 0101 0001 + OP_B_COND, //11 0101 0010 + OP_B_COND, //11 0101 0011 + OP_B_COND, //11 0101 0100 + OP_B_COND, //11 0101 0101 + OP_B_COND, //11 0101 0110 + OP_B_COND, //11 0101 0111 + OP_B_COND, //11 0101 1000 + OP_B_COND, //11 0101 1001 + OP_B_COND, //11 0101 1010 + OP_B_COND, //11 0101 1011 + OP_B_COND, //11 0101 1100 + OP_B_COND, //11 0101 1101 + OP_B_COND, //11 0101 1110 + OP_B_COND, //11 0101 1111 + + OP_B_COND, //11 0110 0000 + OP_B_COND, //11 0110 0001 + OP_B_COND, //11 0110 0010 + OP_B_COND, //11 0110 0011 + OP_B_COND, //11 0110 0100 + OP_B_COND, //11 0110 0101 + OP_B_COND, //11 0110 0110 + OP_B_COND, //11 0110 0111 + OP_B_COND, //11 0110 1000 + OP_B_COND, //11 0110 1001 + OP_B_COND, //11 0110 1010 + OP_B_COND, //11 0110 1011 + OP_B_COND, //11 0110 1100 + OP_B_COND, //11 0110 1101 + OP_B_COND, //11 0110 1110 + OP_B_COND, //11 0110 1111 + + OP_B_COND, //11 0111 0000 + OP_B_COND, //11 0111 0001 + OP_B_COND, //11 0111 0010 + OP_B_COND, //11 0111 0011 + OP_B_COND, //11 0111 0100 + OP_B_COND, //11 0111 0101 + OP_B_COND, //11 0111 0110 + OP_B_COND, //11 0111 0111 + OP_B_COND, //11 0111 1000 + OP_B_COND, //11 0111 1001 + OP_B_COND, //11 0111 1010 + OP_B_COND, //11 0111 1011 + OP_SWI_THUMB, //11 0111 1100 + OP_SWI_THUMB, //11 0111 1101 + OP_SWI_THUMB, //11 0111 1110 + OP_SWI_THUMB, //11 0111 1111 + + OP_B_UNCOND, //11 1000 0000 + OP_B_UNCOND, //11 1000 0001 + OP_B_UNCOND, //11 1000 0010 + OP_B_UNCOND, //11 1000 0011 + OP_B_UNCOND, //11 1000 0100 + OP_B_UNCOND, //11 1000 0101 + OP_B_UNCOND, //11 1000 0110 + OP_B_UNCOND, //11 1000 0111 + OP_B_UNCOND, //11 1000 1000 + OP_B_UNCOND, //11 1000 1001 + OP_B_UNCOND, //11 1000 1010 + OP_B_UNCOND, //11 1000 1011 + OP_B_UNCOND, //11 1000 1100 + OP_B_UNCOND, //11 1000 1101 + OP_B_UNCOND, //11 1000 1110 + OP_B_UNCOND, //11 1000 1111 + + OP_B_UNCOND, //11 1001 0000 + OP_B_UNCOND, //11 1001 0001 + OP_B_UNCOND, //11 1001 0010 + OP_B_UNCOND, //11 1001 0011 + OP_B_UNCOND, //11 1001 0100 + OP_B_UNCOND, //11 1001 0101 + OP_B_UNCOND, //11 1001 0110 + OP_B_UNCOND, //11 1001 0111 + OP_B_UNCOND, //11 1001 1000 + OP_B_UNCOND, //11 1001 1001 + OP_B_UNCOND, //11 1001 1010 + OP_B_UNCOND, //11 1001 1011 + OP_B_UNCOND, //11 1001 1100 + OP_B_UNCOND, //11 1001 1101 + OP_B_UNCOND, //11 1001 1110 + OP_B_UNCOND, //11 1001 1111 + + OP_BLX, //11 1010 0000 + OP_BLX, //11 1010 0001 + OP_BLX, //11 1010 0010 + OP_BLX, //11 1010 0011 + OP_BLX, //11 1010 0100 + OP_BLX, //11 1010 0101 + OP_BLX, //11 1010 0110 + OP_BLX, //11 1010 0111 + OP_BLX, //11 1010 1000 + OP_BLX, //11 1010 1001 + OP_BLX, //11 1010 1010 + OP_BLX, //11 1010 1011 + OP_BLX, //11 1010 1100 + OP_BLX, //11 1010 1101 + OP_BLX, //11 1010 1110 + OP_BLX, //11 1010 1111 + + OP_BLX, //11 1011 0000 + OP_BLX, //11 1011 0001 + OP_BLX, //11 1011 0010 + OP_BLX, //11 1011 0011 + OP_BLX, //11 1011 0100 + OP_BLX, //11 1011 0101 + OP_BLX, //11 1011 0110 + OP_BLX, //11 1011 0111 + OP_BLX, //11 1011 1000 + OP_BLX, //11 1011 1001 + OP_BLX, //11 1011 1010 + OP_BLX, //11 1011 1011 + OP_BLX, //11 1011 1100 + OP_BLX, //11 1011 1101 + OP_BLX, //11 1011 1110 + OP_BLX, //11 1011 1111 + + OP_BL_10, //11 1100 0000 + OP_BL_10, //11 1100 0001 + OP_BL_10, //11 1100 0010 + OP_BL_10, //11 1100 0011 + OP_BL_10, //11 1100 0100 + OP_BL_10, //11 1100 0101 + OP_BL_10, //11 1100 0110 + OP_BL_10, //11 1100 0111 + OP_BL_10, //11 1100 1000 + OP_BL_10, //11 1100 1001 + OP_BL_10, //11 1100 1010 + OP_BL_10, //11 1100 1011 + OP_BL_10, //11 1100 1100 + OP_BL_10, //11 1100 1101 + OP_BL_10, //11 1100 1110 + OP_BL_10, //11 1100 1111 + + OP_BL_10, //11 1101 0000 + OP_BL_10, //11 1101 0001 + OP_BL_10, //11 1101 0010 + OP_BL_10, //11 1101 0011 + OP_BL_10, //11 1101 0100 + OP_BL_10, //11 1101 0101 + OP_BL_10, //11 1101 0110 + OP_BL_10, //11 1101 0111 + OP_BL_10, //11 1101 1000 + OP_BL_10, //11 1101 1001 + OP_BL_10, //11 1101 1010 + OP_BL_10, //11 1101 1011 + OP_BL_10, //11 1101 1100 + OP_BL_10, //11 1101 1101 + OP_BL_10, //11 1101 1110 + OP_BL_10, //11 1101 1111 + + OP_BL_THUMB, //11 1110 0000 + OP_BL_THUMB, //11 1110 0001 + OP_BL_THUMB, //11 1110 0010 + OP_BL_THUMB, //11 1110 0011 + OP_BL_THUMB, //11 1110 0100 + OP_BL_THUMB, //11 1110 0101 + OP_BL_THUMB, //11 1110 0110 + OP_BL_THUMB, //11 1110 0111 + OP_BL_THUMB, //11 1110 1000 + OP_BL_THUMB, //11 1110 1001 + OP_BL_THUMB, //11 1110 1010 + OP_BL_THUMB, //11 1110 1011 + OP_BL_THUMB, //11 1110 1100 + OP_BL_THUMB, //11 1110 1101 + OP_BL_THUMB, //11 1110 1110 + OP_BL_THUMB, //11 1110 1111 + + OP_BL_THUMB, //11 1111 0000 + OP_BL_THUMB, //11 1111 0001 + OP_BL_THUMB, //11 1111 0010 + OP_BL_THUMB, //11 1111 0011 + OP_BL_THUMB, //11 1111 0100 + OP_BL_THUMB, //11 1111 0101 + OP_BL_THUMB, //11 1111 0110 + OP_BL_THUMB, //11 1111 0111 + OP_BL_THUMB, //11 1111 1000 + OP_BL_THUMB, //11 1111 1001 + OP_BL_THUMB, //11 1111 1010 + OP_BL_THUMB, //11 1111 1011 + OP_BL_THUMB, //11 1111 1100 + OP_BL_THUMB, //11 1111 1101 + OP_BL_THUMB, //11 1111 1110 + OP_BL_THUMB, //11 1111 1111 +}; //1089 + diff --git a/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/types.h b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/types.h new file mode 100755 index 000000000..318c38022 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/src/vio2sf/desmume/types.h @@ -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 +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 diff --git a/Frameworks/vio2sf/vio2sf/vio2sf-Info.plist b/Frameworks/vio2sf/vio2sf/vio2sf-Info.plist new file mode 100644 index 000000000..6b816e535 --- /dev/null +++ b/Frameworks/vio2sf/vio2sf/vio2sf-Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + net.kode54.vio2sf + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSHumanReadableCopyright + Copyright © 2013 Christopher Snowhill. All rights reserved. + NSPrincipalClass + + + diff --git a/Info.plist b/Info.plist index 8b83fea7f..c457a780f 100644 --- a/Info.plist +++ b/Info.plist @@ -22,6 +22,21 @@ CFBundleTypeRole None + + CFBundleTypeExtensions + + 2sf + mini2sf + + LSTypeIsPackage + + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + vg.icns + CFBundleTypeName + Nintendo DS Audio File + CFBundleTypeExtensions diff --git a/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj b/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj index aaf028062..5e7551fc1 100644 --- a/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj +++ b/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj @@ -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 = ""; }; 8360EF3E17F92C91005208A4 /* HighlyExperimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyExperimental.xcodeproj; path = ../../Frameworks/HighlyExperimental/HighlyExperimental.xcodeproj; sourceTree = ""; }; 83848FE61807623F00E7332D /* SSEQPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SSEQPlayer.xcodeproj; path = ../../Frameworks/SSEQPlayer/SSEQPlayer.xcodeproj; sourceTree = ""; }; + 83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = vio2sf.xcodeproj; path = ../../Frameworks/vio2sf/vio2sf.xcodeproj; sourceTree = ""; }; + 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 = ""; @@ -280,6 +304,14 @@ name = Products; sourceTree = ""; }; + 83DE0C35180A9BD400269051 /* Products */ = { + isa = PBXGroup; + children = ( + 83DE0C3A180A9BD500269051 /* vio2sf.framework */, + ); + name = Products; + sourceTree = ""; + }; /* 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 */ diff --git a/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm b/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm index 2206d8b0b..b36e6aae9 100644 --- a/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm +++ b/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm @@ -28,6 +28,10 @@ #import #import +#import + +#include + @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 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