diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..e376c21 --- /dev/null +++ b/.clang-format @@ -0,0 +1,93 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: AcrossEmptyLinesAndComments +AlignConsecutiveBitFields: AcrossEmptyLinesAndComments +AlignConsecutiveDeclarations: None +AlignConsecutiveMacros: AcrossEmptyLinesAndComments +AlignEscapedNewlinesLeft: Left +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Empty +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing : Both +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: false + BeforeElse: true + BeforeLambdaBody: true + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: BeforeComma +ColumnLimit: 0 +CommentPragmas: '^ (IWYU pragma:|NOLINT)' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ForEachMacros: [] +IndentExternBlock: NoIndent +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 3 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6b82b76 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig: http://EditorConfig.org + +# Top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +# 4 spaces indentation +[*.{c,h,js,css,html}] +indent_style = space +indent_size = 4 + +# Tab indentation +[Makefile*,Rules*] +indent_style = tab diff --git a/.github/ISSUE_TEMPLATE/issue-report.yml b/.github/ISSUE_TEMPLATE/issue-report.yml new file mode 100644 index 0000000..6815a38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue-report.yml @@ -0,0 +1,37 @@ +name: Issue report +description: Create a report to help us improve +title: "[ISSUE]: " +labels: [bug] +body: + - type: markdown + attributes: + value: | + ### __Disclaimer:__ + In order to provide you the help we need your console data: nvram backup file and sticker photo. + + - type: checkboxes + id: terms + attributes: + label: Checks + description: "Check before posting" + options: + - label: I provided nvram backup file + - label: I provided sticker photo + + - type: textarea + id: explanation + attributes: + label: Describe the issue + description: A clear and concise description of what the issue is. + placeholder: My issue is... + validations: + required: true + + - type: input + id: console + attributes: + label: Console model + description: you can see it on the console sticker or inside OSDSYS (press triangle on main menú) + placeholder: SCPH-????? + validations: + required: true diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml new file mode 100644 index 0000000..b1e6fba --- /dev/null +++ b/.github/workflows/compilation.yml @@ -0,0 +1,80 @@ +name: CI-compile + +on: + push: + pull_request: + +jobs: + build: + name: MechaPwn compilation + runs-on: ubuntu-latest + container: ghcr.io/ps2homebrew/ps2homebrew:main + # ghcr.io/ps2homebrew/ps2homebrew@sha256:9cf3f8497e5a49e3a08cdf96aa9a5b97f119d554e21e3925b3cc84485846b3ce + # instead of "ps2dev/ps2dev:latest" you can use different tags, for example for old projects you can use "ps2dev/ps2dev:v1.0" + steps: + - name: Install dependencies + run: | + apk add py3-pillow + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Compile project + run: | + make + + # commands for compiling your project + - name: Get short SHA + id: slug + run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT + + - name: Upload artifacts + if: ${{ success() }} + uses: actions/upload-artifact@v4 + with: + name: MechaPwn-${{ steps.slug.outputs.sha8 }} + path: MechaPwn_pck.elf + if-no-files-found: error + + # 'path' will create artifact with all *.elf in working directory + # you can change this + release: + needs: build + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/LangPwn' + steps: + - uses: actions/checkout@v4 + + - name: Get short SHA + id: slug + run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: MechaPwn-${{ steps.slug.outputs.sha8 }} + path: MechaPwn + + - name: Prepare MechaPwn archive + run: 7z a MechaPwn-${{ steps.slug.outputs.sha8 }}.7z MechaPwn/* + + - name: Create pre-release + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/LangPwn' + uses: mathieucarbou/marvinpinto-action-automatic-releases@latest + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + prerelease: true + automatic_release_tag: latest + title: Development build + files: MechaPwn-${{ steps.slug.outputs.sha8 }}.7z + + - name: Create Tagged Release Draft + if: startsWith(github.ref, 'refs/tags/v') + uses: mathieucarbou/marvinpinto-action-automatic-releases@latest + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + prerelease: false + draft: true + automatic_release_tag: RenameMe + files: MechaPwn-${{ steps.slug.outputs.sha8 }}.7z diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c48542 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +*.o +*.irx +*.s +*.pyc +.* +*.elf + +!.github +!.editorconfig +!.clang-format diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000..65651e8 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,24 @@ +# Contributors + +## Special thanks to all the people who had helped this project so far + +* [balika011 (Balázs Triszka)](https://github.com/balika011) - Entire Mechapwn exploit and application development +* [Myriachan](https://github.com/balika011) - mechadumper creator, mechacon firmware disassembler and Force unlock implementation +* [Mathieu HERVAIS (Mathieulh)](https://github.com/mathieulh) - Readme, FAQ, writeup of the exploit, testing on J-chassis +* [AKuHAK](https://github.com/akuhak) - Improvements to the Mechapwn exploit, implementing a fix for DVD Video Player and further application development - Post Force Mexico unlock +* the rest of the MechaPwn team - DSP bug on FAT/70k explanation, DVD Player hacks, register explanation +* [olokos](https://github.com/olokos) - Experimental testing of NVM modifications which helped fix DVD Video - Post Force Mexico unlock +* [Thexterax](https://github.com/Thexterax) and others from the Rayman speedrun community, for helping with fixing the bug on Deckard (not complete PAL/NTSC switch) - Post Force Mexico unlock +* MonkeyBoyJoey - Experimental testing on PSX1/PSX2 +* HowlingWolfHWC - for graphics for PS2 Bravia, PSX1 and PSX2 +* Senyuki for testing on PS2 Bravia KDL-22PX300 +* blckbear, [AndytheGamer329](https://github.com/MechaResearch/MechaPwn/issues/created_by/AndytheGamer329), [hikkamorii](https://github.com/MechaResearch/MechaPwn/issues/83), [angelsix](https://github.com/MechaResearch/MechaPwn/issues/created_by/angelsix), [Cowfood](https://github.com/Cowfood), [CK121212](https://github.com/CK121212), Feng, [ayuayu2](https://github.com/ayuayu2), [elkiot](https://github.com/elkiot), Blondie2282, [SubmergedMaid](https://github.com/SubmergedMaid), Cubelia, [egarjanis](https://github.com/egarjanis), ModzvilleUSA, [KitGit93](https://github.com/KitGit93), [skipper5000](https://github.com/skipper5000), [romechh](https://github.com/romechh), [sixsixsixties](https://github.com/sixsixsixties), Stanley Chan, [nitrostemp](https://github.com/nitrostemp), [Big Boss](https://discord.com/users/Big%20Boss#3689), [spnkhardy](https://github.com/spnkhardy), [israpps](https://github.com/israpps), Simon Huerta Reyes, [RaikouSRL](https://github.com/RaikouSRL), [RosalinaSama](https://github.com/RosalinaSama), [mikepparks](https://github.com/mikepparks), [AnggelGrind](https://github.com/AnggelGrind), [Vladstvo](https://github.com/Vladstvo), [loser2023sgyt](https://github.com/loser2023sgyt), [viarurla](https://github.com/viarurla), Adamdead#0993, Awakening, [jamestoando](https://github.com/jamestoando), [daniel-virtu](https://github.com/daniel-virtu), [CocoaCappuccino](https://github.com/CocoaCappuccino), armorant, [Raiden-64](https://github.com/Raiden-64), [KNIGTBakura](https://github.com/KNIGTBakura), [RaikouSRL](https://github.com/RaikouSRL), [oxosoda](https://github.com/oxosoda), [carlos38841hd](https://github.com/carlos38841hd), [moriohbrew](https://github.com/moriohbrew), [daskrabs](https://github.com/daskrabs), [PenguinTC](https://github.com/PenguinTC), [yji-tan](https://github.com/yji-tan) and others for providing Model IDs and sticker photos. + +## I would like to join this list. How can I help with the project? + +We're currently looking for contributions for the following: + +* [x] Testing on various PS2 models and versions +* [ ] providing missing Model IDs, NVRAM backups and sticker photos + +For more information, please refer to our [CONTRIBUTING](CONTRIBUTING.md) guide - Which is not yet available. diff --git a/Makefile b/Makefile index 4943b02..7b33da9 100644 --- a/Makefile +++ b/Makefile @@ -1,308 +1,58 @@ -EE_BIN = MechaPwn.elf -IRX_DIR = irx/compiled - -# C File -EE_OBJS = main.o mecha.o exploit.o pad.o ui.o mass.o -EE_OBJS += iomanX.o fileXio.o freesio2.o freepad.o mcman.o mcsrv.o USBD.o USBHDFSD.o IndieFlower.o -EE_OBJS += MECHAPROXY_irx.o MASSWATCHER_irx.o pwr50k.o pwr70k.o pwr90k.o frame_001.o frame_002.o frame_003.o frame_004.o frame_005.o frame_006.o frame_007.o frame_008.o frame_009.o frame_010.o frame_011.o frame_012.o frame_013.o frame_014.o frame_015.o frame_016.o frame_017.o frame_018.o frame_019.o frame_020.o frame_021.o frame_022.o frame_023.o frame_024.o frame_025.o frame_026.o frame_027.o frame_028.o frame_029.o frame_030.o frame_031.o frame_032.o frame_033.o frame_034.o frame_035.o frame_036.o frame_037.o frame_038.o frame_039.o frame_040.o frame_041.o frame_042.o frame_043.o frame_044.o frame_045.o frame_046.o frame_047.o frame_048.o frame_049.o frame_050.o frame_051.o frame_052.o frame_053.o frame_054.o frame_055.o frame_056.o frame_057.o frame_058.o frame_059.o frame_060.o frame_061.o frame_062.o - -EE_INCS = -I$(PS2SDK)/ports/include -I$(PS2SDK)/sbv/include -I$(PS2SDK)/common/include -I./irx/source/mechaproxy/include/ -I./irx/source/masswatcher/include/ -I$(PS2SDK)/ports/include/freetype2 -I$(GSKIT)/include -EE_LDFLAGS = -L$(PS2SDK)/sbv/lib -L$(PS2SDK)/ports/lib -L$(GSKIT)/lib -EE_LIBS = -lpatches -lpadx -lmc -lfreetype -lpng16 -lzlib -lgskit -lgskit_toolkit -ldmakit -lfileXio -EE_CFLAGS = -std=c99 - -BIN2S = $(PS2SDK)/bin/bin2s - -all: $(EE_BIN) - rm -rf *.o *.s resources/*.bin resources/*.pyc - -clean: - rm -f *.elf *.o *.s resources/*.bin resources/*.pyc - -#IRX Modules -iomanX.s: - $(BIN2S) $(PS2SDK)/iop/irx/iomanX.irx iomanX.s iomanX -fileXio.s: - $(BIN2S) $(PS2SDK)/iop/irx/fileXio.irx fileXio.s fileXio -freesio2.s: - $(BIN2S) $(PS2SDK)/iop/irx/freesio2.irx freesio2.s freesio2 -freepad.s: - $(BIN2S) $(PS2SDK)/iop/irx/freepad.irx freepad.s freepad -mcman.s: - $(BIN2S) $(PS2SDK)/iop/irx/mcman.irx mcman.s mcman -mcsrv.s: - $(BIN2S) $(PS2SDK)/iop/irx/mcserv.irx mcsrv.s mcserv -USBD.s: $(PS2SDK)/iop/irx/usbd.irx - $(BIN2S) $(PS2SDK)/iop/irx/usbd.irx USBD.s USBD -USBHDFSD.s: $(PS2SDK)/iop/irx/usbhdfsd.irx - $(BIN2S) $(PS2SDK)/iop/irx/usbhdfsd.irx USBHDFSD.s USBHDFSD -MECHAPROXY_irx.s: $(IRX_DIR)/mechaproxy.irx - $(BIN2S) $(IRX_DIR)/mechaproxy.irx MECHAPROXY_irx.s MECHAPROXY_irx -MASSWATCHER_irx.s: $(IRX_DIR)/masswatcher.irx - $(BIN2S) $(IRX_DIR)/masswatcher.irx MASSWATCHER_irx.s MASSWATCHER_irx -IndieFlower.s: resources/IndieFlower-Regular.ttf - $(BIN2S) resources/IndieFlower-Regular.ttf IndieFlower.s IndieFlower -resources/50k.bin: resources/50k.png - python resources/conv.py resources/50k.png resources/50k.bin -pwr50k.s: resources/50k.bin - $(BIN2S) resources/50k.bin pwr50k.s pwr50k -resources/70k.bin: resources/70k.png - python resources/conv.py resources/70k.png resources/70k.bin -pwr70k.s: resources/70k.bin - $(BIN2S) resources/70k.bin pwr70k.s pwr70k -resources/90k.bin: resources/90k.png - python resources/conv.py resources/90k.png resources/90k.bin -pwr90k.s: resources/90k.bin - $(BIN2S) resources/90k.bin pwr90k.s pwr90k - -resources/frame_001.bin: resources/frame_001.png - python resources/conv.py resources/frame_001.png resources/frame_001.bin -frame_001.s: resources/frame_001.bin - $(BIN2S) resources/frame_001.bin frame_001.s frame_001 -resources/frame_002.bin: resources/frame_002.png - python resources/conv.py resources/frame_002.png resources/frame_002.bin -frame_002.s: resources/frame_002.bin - $(BIN2S) resources/frame_002.bin frame_002.s frame_002 -resources/frame_003.bin: resources/frame_003.png - python resources/conv.py resources/frame_003.png resources/frame_003.bin -frame_003.s: resources/frame_003.bin - $(BIN2S) resources/frame_003.bin frame_003.s frame_003 -resources/frame_004.bin: resources/frame_004.png - python resources/conv.py resources/frame_004.png resources/frame_004.bin -frame_004.s: resources/frame_004.bin - $(BIN2S) resources/frame_004.bin frame_004.s frame_004 -resources/frame_005.bin: resources/frame_005.png - python resources/conv.py resources/frame_005.png resources/frame_005.bin -frame_005.s: resources/frame_005.bin - $(BIN2S) resources/frame_005.bin frame_005.s frame_005 -resources/frame_006.bin: resources/frame_006.png - python resources/conv.py resources/frame_006.png resources/frame_006.bin -frame_006.s: resources/frame_006.bin - $(BIN2S) resources/frame_006.bin frame_006.s frame_006 -resources/frame_007.bin: resources/frame_007.png - python resources/conv.py resources/frame_007.png resources/frame_007.bin -frame_007.s: resources/frame_007.bin - $(BIN2S) resources/frame_007.bin frame_007.s frame_007 -resources/frame_008.bin: resources/frame_008.png - python resources/conv.py resources/frame_008.png resources/frame_008.bin -frame_008.s: resources/frame_008.bin - $(BIN2S) resources/frame_008.bin frame_008.s frame_008 -resources/frame_009.bin: resources/frame_009.png - python resources/conv.py resources/frame_009.png resources/frame_009.bin -frame_009.s: resources/frame_009.bin - $(BIN2S) resources/frame_009.bin frame_009.s frame_009 -resources/frame_010.bin: resources/frame_010.png - python resources/conv.py resources/frame_010.png resources/frame_010.bin -frame_010.s: resources/frame_010.bin - $(BIN2S) resources/frame_010.bin frame_010.s frame_010 -resources/frame_011.bin: resources/frame_011.png - python resources/conv.py resources/frame_011.png resources/frame_011.bin -frame_011.s: resources/frame_011.bin - $(BIN2S) resources/frame_011.bin frame_011.s frame_011 -resources/frame_012.bin: resources/frame_012.png - python resources/conv.py resources/frame_012.png resources/frame_012.bin -frame_012.s: resources/frame_012.bin - $(BIN2S) resources/frame_012.bin frame_012.s frame_012 -resources/frame_013.bin: resources/frame_013.png - python resources/conv.py resources/frame_013.png resources/frame_013.bin -frame_013.s: resources/frame_013.bin - $(BIN2S) resources/frame_013.bin frame_013.s frame_013 -resources/frame_014.bin: resources/frame_014.png - python resources/conv.py resources/frame_014.png resources/frame_014.bin -frame_014.s: resources/frame_014.bin - $(BIN2S) resources/frame_014.bin frame_014.s frame_014 -resources/frame_015.bin: resources/frame_015.png - python resources/conv.py resources/frame_015.png resources/frame_015.bin -frame_015.s: resources/frame_015.bin - $(BIN2S) resources/frame_015.bin frame_015.s frame_015 -resources/frame_016.bin: resources/frame_016.png - python resources/conv.py resources/frame_016.png resources/frame_016.bin -frame_016.s: resources/frame_016.bin - $(BIN2S) resources/frame_016.bin frame_016.s frame_016 -resources/frame_017.bin: resources/frame_017.png - python resources/conv.py resources/frame_017.png resources/frame_017.bin -frame_017.s: resources/frame_017.bin - $(BIN2S) resources/frame_017.bin frame_017.s frame_017 -resources/frame_018.bin: resources/frame_018.png - python resources/conv.py resources/frame_018.png resources/frame_018.bin -frame_018.s: resources/frame_018.bin - $(BIN2S) resources/frame_018.bin frame_018.s frame_018 -resources/frame_019.bin: resources/frame_019.png - python resources/conv.py resources/frame_019.png resources/frame_019.bin -frame_019.s: resources/frame_019.bin - $(BIN2S) resources/frame_019.bin frame_019.s frame_019 -resources/frame_020.bin: resources/frame_020.png - python resources/conv.py resources/frame_020.png resources/frame_020.bin -frame_020.s: resources/frame_020.bin - $(BIN2S) resources/frame_020.bin frame_020.s frame_020 -resources/frame_021.bin: resources/frame_021.png - python resources/conv.py resources/frame_021.png resources/frame_021.bin -frame_021.s: resources/frame_021.bin - $(BIN2S) resources/frame_021.bin frame_021.s frame_021 -resources/frame_022.bin: resources/frame_022.png - python resources/conv.py resources/frame_022.png resources/frame_022.bin -frame_022.s: resources/frame_022.bin - $(BIN2S) resources/frame_022.bin frame_022.s frame_022 -resources/frame_023.bin: resources/frame_023.png - python resources/conv.py resources/frame_023.png resources/frame_023.bin -frame_023.s: resources/frame_023.bin - $(BIN2S) resources/frame_023.bin frame_023.s frame_023 -resources/frame_024.bin: resources/frame_024.png - python resources/conv.py resources/frame_024.png resources/frame_024.bin -frame_024.s: resources/frame_024.bin - $(BIN2S) resources/frame_024.bin frame_024.s frame_024 -resources/frame_025.bin: resources/frame_025.png - python resources/conv.py resources/frame_025.png resources/frame_025.bin -frame_025.s: resources/frame_025.bin - $(BIN2S) resources/frame_025.bin frame_025.s frame_025 -resources/frame_026.bin: resources/frame_026.png - python resources/conv.py resources/frame_026.png resources/frame_026.bin -frame_026.s: resources/frame_026.bin - $(BIN2S) resources/frame_026.bin frame_026.s frame_026 -resources/frame_027.bin: resources/frame_027.png - python resources/conv.py resources/frame_027.png resources/frame_027.bin -frame_027.s: resources/frame_027.bin - $(BIN2S) resources/frame_027.bin frame_027.s frame_027 -resources/frame_028.bin: resources/frame_028.png - python resources/conv.py resources/frame_028.png resources/frame_028.bin -frame_028.s: resources/frame_028.bin - $(BIN2S) resources/frame_028.bin frame_028.s frame_028 -resources/frame_029.bin: resources/frame_029.png - python resources/conv.py resources/frame_029.png resources/frame_029.bin -frame_029.s: resources/frame_029.bin - $(BIN2S) resources/frame_029.bin frame_029.s frame_029 -resources/frame_030.bin: resources/frame_030.png - python resources/conv.py resources/frame_030.png resources/frame_030.bin -frame_030.s: resources/frame_030.bin - $(BIN2S) resources/frame_030.bin frame_030.s frame_030 -resources/frame_031.bin: resources/frame_031.png - python resources/conv.py resources/frame_031.png resources/frame_031.bin -frame_031.s: resources/frame_031.bin - $(BIN2S) resources/frame_031.bin frame_031.s frame_031 -resources/frame_032.bin: resources/frame_032.png - python resources/conv.py resources/frame_032.png resources/frame_032.bin -frame_032.s: resources/frame_032.bin - $(BIN2S) resources/frame_032.bin frame_032.s frame_032 -resources/frame_033.bin: resources/frame_033.png - python resources/conv.py resources/frame_033.png resources/frame_033.bin -frame_033.s: resources/frame_033.bin - $(BIN2S) resources/frame_033.bin frame_033.s frame_033 -resources/frame_034.bin: resources/frame_034.png - python resources/conv.py resources/frame_034.png resources/frame_034.bin -frame_034.s: resources/frame_034.bin - $(BIN2S) resources/frame_034.bin frame_034.s frame_034 -resources/frame_035.bin: resources/frame_035.png - python resources/conv.py resources/frame_035.png resources/frame_035.bin -frame_035.s: resources/frame_035.bin - $(BIN2S) resources/frame_035.bin frame_035.s frame_035 -resources/frame_036.bin: resources/frame_036.png - python resources/conv.py resources/frame_036.png resources/frame_036.bin -frame_036.s: resources/frame_036.bin - $(BIN2S) resources/frame_036.bin frame_036.s frame_036 -resources/frame_037.bin: resources/frame_037.png - python resources/conv.py resources/frame_037.png resources/frame_037.bin -frame_037.s: resources/frame_037.bin - $(BIN2S) resources/frame_037.bin frame_037.s frame_037 -resources/frame_038.bin: resources/frame_038.png - python resources/conv.py resources/frame_038.png resources/frame_038.bin -frame_038.s: resources/frame_038.bin - $(BIN2S) resources/frame_038.bin frame_038.s frame_038 -resources/frame_039.bin: resources/frame_039.png - python resources/conv.py resources/frame_039.png resources/frame_039.bin -frame_039.s: resources/frame_039.bin - $(BIN2S) resources/frame_039.bin frame_039.s frame_039 -resources/frame_040.bin: resources/frame_040.png - python resources/conv.py resources/frame_040.png resources/frame_040.bin -frame_040.s: resources/frame_040.bin - $(BIN2S) resources/frame_040.bin frame_040.s frame_040 -resources/frame_041.bin: resources/frame_041.png - python resources/conv.py resources/frame_041.png resources/frame_041.bin -frame_041.s: resources/frame_041.bin - $(BIN2S) resources/frame_041.bin frame_041.s frame_041 -resources/frame_042.bin: resources/frame_042.png - python resources/conv.py resources/frame_042.png resources/frame_042.bin -frame_042.s: resources/frame_042.bin - $(BIN2S) resources/frame_042.bin frame_042.s frame_042 -resources/frame_043.bin: resources/frame_043.png - python resources/conv.py resources/frame_043.png resources/frame_043.bin -frame_043.s: resources/frame_043.bin - $(BIN2S) resources/frame_043.bin frame_043.s frame_043 -resources/frame_044.bin: resources/frame_044.png - python resources/conv.py resources/frame_044.png resources/frame_044.bin -frame_044.s: resources/frame_044.bin - $(BIN2S) resources/frame_044.bin frame_044.s frame_044 -resources/frame_045.bin: resources/frame_045.png - python resources/conv.py resources/frame_045.png resources/frame_045.bin -frame_045.s: resources/frame_045.bin - $(BIN2S) resources/frame_045.bin frame_045.s frame_045 -resources/frame_046.bin: resources/frame_046.png - python resources/conv.py resources/frame_046.png resources/frame_046.bin -frame_046.s: resources/frame_046.bin - $(BIN2S) resources/frame_046.bin frame_046.s frame_046 -resources/frame_047.bin: resources/frame_047.png - python resources/conv.py resources/frame_047.png resources/frame_047.bin -frame_047.s: resources/frame_047.bin - $(BIN2S) resources/frame_047.bin frame_047.s frame_047 -resources/frame_048.bin: resources/frame_048.png - python resources/conv.py resources/frame_048.png resources/frame_048.bin -frame_048.s: resources/frame_048.bin - $(BIN2S) resources/frame_048.bin frame_048.s frame_048 -resources/frame_049.bin: resources/frame_049.png - python resources/conv.py resources/frame_049.png resources/frame_049.bin -frame_049.s: resources/frame_049.bin - $(BIN2S) resources/frame_049.bin frame_049.s frame_049 -resources/frame_050.bin: resources/frame_050.png - python resources/conv.py resources/frame_050.png resources/frame_050.bin -frame_050.s: resources/frame_050.bin - $(BIN2S) resources/frame_050.bin frame_050.s frame_050 -resources/frame_051.bin: resources/frame_051.png - python resources/conv.py resources/frame_051.png resources/frame_051.bin -frame_051.s: resources/frame_051.bin - $(BIN2S) resources/frame_051.bin frame_051.s frame_051 -resources/frame_052.bin: resources/frame_052.png - python resources/conv.py resources/frame_052.png resources/frame_052.bin -frame_052.s: resources/frame_052.bin - $(BIN2S) resources/frame_052.bin frame_052.s frame_052 -resources/frame_053.bin: resources/frame_053.png - python resources/conv.py resources/frame_053.png resources/frame_053.bin -frame_053.s: resources/frame_053.bin - $(BIN2S) resources/frame_053.bin frame_053.s frame_053 -resources/frame_054.bin: resources/frame_054.png - python resources/conv.py resources/frame_054.png resources/frame_054.bin -frame_054.s: resources/frame_054.bin - $(BIN2S) resources/frame_054.bin frame_054.s frame_054 -resources/frame_055.bin: resources/frame_055.png - python resources/conv.py resources/frame_055.png resources/frame_055.bin -frame_055.s: resources/frame_055.bin - $(BIN2S) resources/frame_055.bin frame_055.s frame_055 -resources/frame_056.bin: resources/frame_056.png - python resources/conv.py resources/frame_056.png resources/frame_056.bin -frame_056.s: resources/frame_056.bin - $(BIN2S) resources/frame_056.bin frame_056.s frame_056 -resources/frame_057.bin: resources/frame_057.png - python resources/conv.py resources/frame_057.png resources/frame_057.bin -frame_057.s: resources/frame_057.bin - $(BIN2S) resources/frame_057.bin frame_057.s frame_057 -resources/frame_058.bin: resources/frame_058.png - python resources/conv.py resources/frame_058.png resources/frame_058.bin -frame_058.s: resources/frame_058.bin - $(BIN2S) resources/frame_058.bin frame_058.s frame_058 -resources/frame_059.bin: resources/frame_059.png - python resources/conv.py resources/frame_059.png resources/frame_059.bin -frame_059.s: resources/frame_059.bin - $(BIN2S) resources/frame_059.bin frame_059.s frame_059 -resources/frame_060.bin: resources/frame_060.png - python resources/conv.py resources/frame_060.png resources/frame_060.bin -frame_060.s: resources/frame_060.bin - $(BIN2S) resources/frame_060.bin frame_060.s frame_060 -resources/frame_061.bin: resources/frame_061.png - python resources/conv.py resources/frame_061.png resources/frame_061.bin -frame_061.s: resources/frame_061.bin - $(BIN2S) resources/frame_061.bin frame_061.s frame_061 -resources/frame_062.bin: resources/frame_062.png - python resources/conv.py resources/frame_062.png resources/frame_062.bin -frame_062.s: resources/frame_062.bin - $(BIN2S) resources/frame_062.bin frame_062.s frame_062 - -include $(PS2SDK)/samples/Makefile.pref -include $(PS2SDK)/samples/Makefile.eeglobal +EE_BIN = MechaPwn.elf +IRX_DIR = irx/compiled +EE_PACKED_BIN = MechaPwn_pck.elf + +# C File +EE_OBJS = main.o mecha.o exploit.o pad.o ui.o mass.o +EE_OBJS += iomanX_irx.o fileXio_irx.o freesio2_irx.o freepad_irx.o mcman_irx.o mcsrv_irx.o USBD_irx.o USBHDFSD_irx.o IndieFlower_irx.o +EE_OBJS += MECHAPROXY_irx.o MASSWATCHER_irx.o pwr50k.o pwr70k.o pwr90k.o pwrpsx1.o pwrpsx2.o pwrtvcombo.o frame_001.o frame_002.o frame_003.o frame_004.o frame_005.o frame_006.o frame_007.o frame_008.o frame_009.o frame_010.o frame_011.o frame_012.o frame_013.o frame_014.o frame_015.o frame_016.o frame_017.o frame_018.o frame_019.o frame_020.o frame_021.o frame_022.o frame_023.o frame_024.o frame_025.o frame_026.o frame_027.o frame_028.o frame_029.o frame_030.o frame_031.o frame_032.o frame_033.o frame_034.o frame_035.o frame_036.o frame_037.o frame_038.o frame_039.o frame_040.o frame_041.o frame_042.o frame_043.o frame_044.o frame_045.o frame_046.o frame_047.o frame_048.o frame_049.o frame_050.o frame_051.o frame_052.o frame_053.o frame_054.o frame_055.o frame_056.o frame_057.o frame_058.o frame_059.o frame_060.o frame_061.o frame_062.o + +EE_INCS = -I$(PS2SDK)/ports/include -I$(PS2SDK)/sbv/include -I$(PS2SDK)/common/include -I./irx/source/mechaproxy/include/ -I./irx/source/masswatcher/include/ -I$(PS2SDK)/ports/include/freetype2 -I$(GSKIT)/include +EE_LDFLAGS = -L$(PS2SDK)/sbv/lib -L$(PS2SDK)/ports/lib -L$(GSKIT)/lib +EE_LIBS = -lpatches -lpadx -lmc -lfreetype -lpng -lz -lgskit -lgskit_toolkit -ldmakit -lfileXio +EE_CFLAGS = -std=c99 + +BIN2C = $(PS2SDK)/bin/bin2c + +all: $(EE_BIN) + ps2-packer $(EE_BIN) $(EE_PACKED_BIN) + +clean: + make clean -C irx/source/mechaproxy + make clean -C irx/source/masswatcher + rm -f *.elf *.o *_irx.c *.s resources/*.bin resources/*.pyc *.pyc + +#IRX Modules +iomanX_irx.c: + $(BIN2C) $(PS2SDK)/iop/irx/iomanX.irx iomanX_irx.c iomanX +fileXio_irx.c: + $(BIN2C) $(PS2SDK)/iop/irx/fileXio.irx fileXio_irx.c fileXio +freesio2_irx.c: + $(BIN2C) $(PS2SDK)/iop/irx/freesio2.irx freesio2_irx.c freesio2 +freepad_irx.c: + $(BIN2C) $(PS2SDK)/iop/irx/freepad.irx freepad_irx.c freepad +mcman_irx.c: + $(BIN2C) $(PS2SDK)/iop/irx/mcman.irx mcman_irx.c mcman +mcsrv_irx.c: + $(BIN2C) $(PS2SDK)/iop/irx/mcserv.irx mcsrv_irx.c mcserv +USBD_irx.c: $(PS2SDK)/iop/irx/usbd.irx + $(BIN2C) $(PS2SDK)/iop/irx/usbd.irx USBD_irx.c USBD +USBHDFSD_irx.c: $(PS2SDK)/iop/irx/usbhdfsd.irx + $(BIN2C) $(PS2SDK)/iop/irx/usbhdfsd.irx USBHDFSD_irx.c USBHDFSD +MECHAPROXY_irx.c: + $(MAKE) -C irx/source/mechaproxy + $(BIN2C) irx/source/mechaproxy/irx/mechaproxy.irx MECHAPROXY_irx.c MECHAPROXY_irx +MASSWATCHER_irx.c: + $(MAKE) -C irx/source/masswatcher + $(BIN2C) irx/source/masswatcher/irx/masswatcher.irx MASSWATCHER_irx.c MASSWATCHER_irx +IndieFlower_irx.c: resources/IndieFlower-Regular.ttf + $(BIN2C) resources/IndieFlower-Regular.ttf IndieFlower_irx.c IndieFlower + +%.c: resources/% + $(BIN2C) $^ $@ $(^F) + +resources/%: resources/%.png + python3 resources/conv.py $^ $@ + +include $(PS2SDK)/samples/Makefile.pref +include $(PS2SDK)/samples/Makefile.eeglobal diff --git a/README.md b/README.md index 4dd616f..d9b69b1 100644 --- a/README.md +++ b/README.md @@ -1,117 +1,167 @@ # MechaPwn -## For questions @ [me on twitter.com](https://twitter.com/balika011). -Any issue opened that not an actual issue, but a question will be closed. +[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/cloudposse.svg?style=flat&logo=Twitter&label=Follow%20%40balika011)](https://twitter.com/balika011) [![Discord](https://img.shields.io/discord/652861436992946216?style=flat&logo=Discord)](https://discord.gg/CVFUa9xh6B) -## Disclaimer: DO NOT USE A ON A REAL DTL/DEX; This sets the QA flag which forces the use of the retail keystore, this would break memory card compatibility. +Any issue opened that is not an actual issue, but a question will be closed. -Real DEX (non QA) flags have not been added to the public version of mechapwn for your own safety. +> :warning: Deckard[^3] users: Disclaimer: if you use FMCB, ensure that you have installed the **cross-region** version. :warning: +> :warning: non-Deckard (FAT[^5] and 70k[^7]) users: Disclaimer: bad quality disks can damage your laser (with or without MechaPwn, doesn't matter). More info [here](#dsp-limitations). :warning: +Real DEX (non-QA) flags have not been added to the public version of MechaPwn for your safety. -The authors hold no responsibility should you break/damage your Playstation 2 console using this software +The authors hold no responsibility should you break/damage your PlayStation 2 console using this software. -This tool can be used to change the region and configuration flags from Dragon based mechacon consoles +- This tool can be used to change the Mechacon region and configuration flags for Dragon[^2] units. +- This tool can be used to change the OSD region/language set and DVD player region for 70k[^7] and Deckard[^3] units. +- This tool can be used to change the PS2 Disk region and PS1 Disk region for Deckard[^3] units. -This means Playstation 2 consoles from the SCPH-5000X systems all the way to the SCPH-90000X are supported -(with the exception of the DESR (PSX) consoles which are not supported at this time, a future update is planned to address this) +Older[^1] consoles do NOT use a Dragon-based mechacon and therefore are not supported. No support is planned for those in the future. But you will get a valid NVRAM backup and basic information about your Mechacon chip and console. -Older Playstation 2 units do NOT use a Dragon based mechacon and therefore are not supported, no support is planned for those in the future. +## FMCB and DVD player -### How to use? +- Deckard[^3]-only: FMCB uses `systemupdate exploit` depending `rom0:ROMVER` region letter. On Deckard[^3] units, MechaPwn can change the region letter: the DEX option will install `A` region for any selected region, CEX option will use a region-specific letter. To avoid broken FMCB, install the FMCB cross-region before using MechaPwn. +- CEX option only: FMCB 1.8 and older are region locked. It will stop working if you change the region under the CEX option. To avoid this - use only the DEX option or upgrade to FMCB 1.9 +- CEX option only: DVD player on Pre-Deckard[^4] models is region locked. It (and DVD player-based exploits like FreeDVDBoot) will stop working if you change the region under the CEX option. To avoid this - use only the DEX option or install a DVD player update to the memory card. +- Force Unlock will disable the DVD player +- Deckard[^3]-only, PAL and Japan units only: FMCB, dvdplayer hack from krHACKen, gameplay history, etc will change their location. If you don't want to lose functionality, ensure that all `B?EXEC-` and `B?SYSTEM-` folders have their content copied into respective `BAEXEC-` and `BASYSTEM-` folders. -0) Make sure if you are using FMCB **you have v1.966 "multi install" installed**. +## How to use it? -1) Run Mechapwn once to install the exploit patch/payload an initial backup of your mechacon eeprom will be made to the usb mass storage device (keep it safe!),then power off the console by disconnecting it from the mains when asked (mechacon is on even when the ps2 cpu is off, so you really need to disconnect the power chord!) -2) Run Mechapwn again to choose which region you want. -3) Choose whether you want to use force unlock or restore the original patch set (and uninstall the exploit patch) from your mechacon backup. +0) Make sure if you are using FMCB **you have "CROSS-REGION" installed**. -*You will need to reinstall the exploit patch to change your region again* +1) Run MechaPwn once to install the exploit patch/payload. An initial backup of your mechacon EEPROM will be made to the USB mass storage device (keep it safe!), then power off the console by disconnecting it from the mains when asked (mechacon is on, even when the ps2 CPUs is off, so you MUST disconnect the power cord!) +2) Run MechaPwn again to choose which region you want. +3) Choose whether you want to use: keep the current patch from your mechacon backup, restore factory default or install force unlock. The safest option - keep the current patch. -#### Explanations of the menu options: +_You will need to reinstall the exploit patch to change your region again_ -CEX (Retail) will just set the region flag and machine ID of your chosing (it is not advised to mix and match different machine ID types, for example setting an SCPH-75001 ID to an SCPH-50004 console. +### Explanations of the app screens -Retail-DEX (Debug) will let you set a QA Flagged DEX configuration/region with a DEX machine ID of your chosing, this allows mechacon to read discs from all regions as well as masterdiscs (the retail option does not). +MechaPwn logo will wait until the USB device is ready. +Backup nvram. MechaPwn will backup your console NVRAM data to the USB device. This will work on any console, so the app can be used for dumping NVRAM. -How does it work? +Information screen. Will show data about your console: Serial number, model ID, real model name, mechacon firmware version and timestamp. If your console is untested or unsupported, MechaPwn will block itself. If you see a message "please report ..." feel free to open an issue and your console data will be tested for compatibility with MechaPwn. -The Dragon based MechaCon (SCPH-500xx and newer) store configuration flags and patches encrypted in their eeprom, the patch DES key was eventually bruteforced which allowed code execution on those units and for the full keystore to be dumped. +FMCB check. For slim consoles, MechaPwn will check that FMCB is installed for the US region. Again, please use FMCB cross-region install. If you have a compatible FMCB, this screen will be skipped. -Normally the patch area is write protected and cannot be written to at runtime except while using PMAP in TEST mode (this requires soldering) furthermore the configuration area can only be written to when it is empty. +The next screen will allow you to change the region or restore the saved NVRAM backup from the USB. -This is done to prevent an attacker or anyone outside of Sony's own factory to overwrite mechacon configuration. +Console type screen. DEX will set a QA Flagged DEX configuration/region and clear all common region flags. This allows mechacon to read discs from all regions as well as masterdiscs (the retail option does not). This also allows executing all-region kelfs. On Deckard[^3], this also forces NTSC video mode and forces PS2 and PS1 titles to run in the NA region. On FAT[^5] CEX option is disabled as confirmed to be too dangerous. On slims, CEX (Retail) will just set the region flag of your choosing. This option also restricts other regions from running. -However an exploitable bug was found in the writeconfig function which allows to write arbitrary data to the patch area, +The next screen will allow choosing between predefined region sets on slims (70k[^7] and Deckard[^3]). It will change OSD behavior (for example, language set) and DVD Player region. Keep in mind that the DEX type will use NTSC-U for PS2 and PS1 titles in any region. -this allows to write a mechacon patch which disables the write protection on mechacon configuration bits and thus set specific regions and flags to mechacon. +Patch menu. This menu will allow you to keep the current patch, install factory defaults and install force unlock. Factory Defaults will allow you to uninstall Force Unlock. +### How does it work? -This allows the following: +The Dragon[^2]-based MechaCon store configuration flags and patches were encrypted in their EEPROM, and the patch DES key was eventually brute-forced, thus allowing code execution on those units and for the full keystore to be dumped. -On SCPH-500xx and SCPH-700xx: +Normally, the patch area is write-protected and cannot be written to at runtime except while using PMAP in TEST mode (this requires soldering). Furthermore, the configuration area can only be written when it is empty. -* Disable disc region checks (ps1 and ps2 discs from all region as well as masterdiscs mount with data accessible) +This is done to prevent an attacker or anyone outside of Sony's factory from overwriting the mechacon configuration. -* Change the region the console reports as, as well as change the disc/kelf region that mechacon allows +However, an exploitable bug was found in the WriteConfig function that allows writing arbitrary data to the patch area. This allows writing a mechacon patch that disables the write protection on mechacon configuration bits and thus sets specific regions and flags to mechacon. -* BOOT original PS2 discs from NTSC-J and NTSC-U regions directly from the OSD (NTSC-J units only) +### DSP limitations -* BOOT original PS2 discs all regions directly from the OSD (NTSC-U and ASIA (non NTSC-J) units only) +1. Burning coils. It is NOT MECHAPWN fault!!! It is a hardware bug, you are risking every time you put the burned disk into FAT[^5] and 70k[^7]. Affects any FAT[^5] and 70k[^7] consoles. If a disc has bad ECC (error correction) data on the error correction area of each sector, there's a chance it may crash the DSP during a read, given that the coils are driven using PWM (pulse width modulation) there's a 50% chance it may crash while the coil is energized. The coil is not designed to receive constant current so it can be damaged. It doesn't crash with silver discs (without scrapes), it **may** crash with burnt discs, it only depends if the ECC data is bogus or not. While this problem is not caused by MechaPwn, our team understands that after MechaPwn you will have more reasons to put burned disks inside. You are warned! The only working fix for preventing this - is `Matrix PIC fix` that shut down the system in case of an ECC error. All other passive fixes are not working. The other way for fixing this: replace the DSP chip with some DTL DSP chip (that is marked -1). [More details about Matrix PIC fix](docs/PICfix.md). +2. DSP does not store disk keys (16 bytes) inside its registers. This only affects retail units, real DTL units do not have this `bug?/feature?` cause DTL units have another DSP chip revision. The mechacon copies disc ID data from the masterdisc sector into the DSP registers and later in CDVDMAN on DTL units. Retail DSP always read back from the disc. This will block MasterPatched disks from running directly from OSD. -* BOOT original PS2 discs all regions as well as PS2 Masterdiscs from all region by skipping the logo check (for example by loading a disc using ulaunchelf) +## Program Advantages -* NTSC-J and PAL consoles: BOOT PS1 disc originals from the console's original region +DEX option allows the following: -* NTSC-U and ASIA (non NTSC-J) consoles: BOOT PS1 disc originals from all regions +On all units +- Disable disc region checks (ps1 and ps2 discs from all-region as well as masterdiscs mount with data accessible) +- Change the region the console reports as, as well as change the disc/KELF region that mechacon allows +- Boot burned PS1 backups from the console's original region directly from OSD +- Boot burned PS2 CD disks from the console's original region directly from OSD (without masterpatch) +- Boot masterpatched PS2 backups and original PS2 disks from all-region by skipping the logo check (for example, by loading a disc using [wlaunchELF](https://github.com/ps2homebrew/wLaunchELF)) +- 70k[^7] and Deckard[^3] only: Change OSD and DVD region +- Deckard[^3] only: force NTSC-U region and video mode for PS2/PS1 titles +On all-region Deckard[^3] units, FAT[^5]/70k[^7] units from regions North America or Asia additionally -On SCPH-7500X and later models (also known as Deckard consoles) +- Boot burned PS1 backups, original PS1 and PS2 disks from all-region directly from OSD -* Disable disc region checks (ps1 and ps2 discs from all region as well as masterdiscs mount with data accessible) +### FAQ -* Change the IOP ROM region (the ROM sets a specific bank according to the mechacon region flags) +#### How to update from MechaPwn 2.0 to MechaPwn 3.0? -* Change the region the console reports as, as well as change the disc/kelf region that mechacon allows +Do not use the *Restore Backup* option with MechaPwn 2.0 until you are sure that the NVRAM backup is not corrupted. +MechaPwn 3.0 cannot fix your model name, so you need to restore it with MechaPwn 2.0. With MechaPwn 2.0 install *CEX* option for your model. With MechaPwn 3.0 install whatever you want. If you want to get rid of *Force Unlock*, choose *Restore Factory _Defaults_ in the Patches menu. -* BOOT original PS2 discs all regions directly from the OSD +#### I have a message "Unknown ***, please report"? -* BOOT original PS2 discs all regions as well as PS2 Masterdiscs from all region by skipping the logo check (for example by loading a disc using ulaunchelf) +That means that your console setup was untested. Please provide an NVRAM backup and sticker photo for further research. -* BOOT PS1 disc originals from all regions +#### Why does my screen get noisy and blurry? +Your TV doesn't support NTSC or PAL signal. MechaPwn can change the default video mode, for example, DEX on Deckard[^3] units will force NTSC video mode. Choose the CEX option or use different TV. -FAQ: +#### Why do PAL/NTSC-J consoles not play NTSC/PAL discs (on FAT[^5] and 70k[^7])? -### Why do PAL/NTSC-J consoles do not play NTSC/PAL discs (on scph-70000 and earlier) ? +The IOP ROM on those consoles has enforced strict logo decryption checks both in the PS1 and PS2 BOOTROM that the NTSC-U (also used in ASIA consoles) BOOTROM does not have. -The IOP ROM on those consoles have enforced strict logo decryption checks both in the PS1 and PS2 BIOS which the NTSC-U (also used in ASIA consoles) BIOS does not have. +#### PS1 game has issues, stretched screen, abnormal behavior, etc. +If PS1 games are acting incorrectly, we advise using [DKWDRV](https://github.com/wisi-w/DKWDRV) which has many fixes for the PS1 mode. -### Why do consoles not run masterdiscs directly from the OSD? +#### How to play PS1 games from the different regions on PAL/NTSC-J FAT[^5] and 70k[^7] (original and backups)? -An additional protection exists on the DSP, which is different in retail and debug consoles, the debug one allows mechacon to store the masterdisc xor key in its registers, the retail one does not. -Bypassing the logo check bypasses this protection (this can be done using ule or a future cdvdman patch using a ps2 homebrew) +You can do this only via the swap trick. For example, you can burn *ImportPlayer _Lite 2.1_ for either PAL or Japan (according to your console's original region) and follow the instructions for disk swap in the program. Keep in mind that game compatibility will not apply and video mode should be set with *ImportPlayer _Lite 2.1_. -### My PS2 has a modchip. Will it work for me? +#### Why do consoles not run masterdiscs directly from the OSD? -We don't know. This depends on what modchip you are using, it has been reported that some revisions of the modbo 4.0 chip do not truly disable when "disabled" causing conflicts/compatibility issues with mechapwn region changes, whereas we have seen it work with a modbo 5.0 with disable that does work as intended (with all modchip features still working when enabled on the converted console). +Additional protection exists on the DSP, which is different in retail and debug consoles, the debug one allows mechacon to store the masterdisc XOR key in its registers, but the retail one does not. +Bypassing the logo check bypasses this protection (this can be done using [wlaunchELF](https://github.com/ps2homebrew/wLaunchELF) or a future cdvdman patch using a ps2 homebrew) -### Why is my PS2 doesn't play DVDs anymore / FreeDVDBoot stopped working? +#### My PS2 has a modchip. Will it work for me? -The DVD Player KELF inside the BootROM (BIOS) is region locked on non-deckard (pre SCPH-750XX). Since you changed the region of the console it can't run that file. -To fix that you need to install a DVD Player update to your memory card. +We don't know. This depends on what modchip you are using. It has been reported that some revisions of the modbo 4.0 chip do not truly disable when "disabled" causing conflicts/compatibility issues with MechaPwn region changes, whereas we have seen it work with a modbo 5.0 with disabling that does work as intended (with all modchip features still working when enabled on the converted console). -### Why did FreeMCBoot stopped working? +#### What is Force Unlock? -Version 1.8 is piggybacking a DVD Player KELF and faces the same issue as DVD Player players. +Force-Unlock is a feature for homebrew applications, like Neo Geo emulation, PS2 Linux for reading CD and DVD-ROM discs. +What it's meant to do is unlock the disk drive for access. -Version 1.9 is supported, but you have to make sure you have the multi-region ("multi install") version installed. +> :warning: Important note: If you enable Force Unlock every CD and DVD will be detected as a PS2 disc, meaning it breaks PS1 games and DVD-Video** -### What is force unlock? +#### How to create a master patched disk? -Force-Unlock is a very much needed feature for homebrew applications, like Neo Geo emulation, PS2 Linux for reading CD and DVD-ROM discs. -What it's meant to do is unlock the disk drive for access. +Master patch creation isnt covered by this FAQ. Try to search for *PSX/PS2 Disc Patcher v3.0* or official SONY utilities. + +#### What are the advantages of use on PSX[^6] DVR units? + +PSX DVR units mostly have the same limitations as Japan FAT[^5] consoles, but the DEX option in MechaPwn will allow PSX DVR to play PS2 disks from any region directly from XMB. PS1 titles still require the Japanese sector on the disk. Note, that you need a functional burning laser even if you do not plan to record disks to play PS2/PS1 titles. + +## TODO / Known bugs and limitations / Planned work + +70k[^7] consoles with mechacon 6.0 and 6.2 will break DVD Player support (so exploits like FreeDVDPlayer will stop working). 70k[^7] consoles with mechacon 6.4 are not affected by this behavior. +FMCB will bootloop with Force Unlock and PS2DVD. +Check NVRAM lens area, for better laser calibration. +Collect all possible Model IDs + sticker photo. +Develop an app for restoring nvram based on sticker photos. +Improve Force Unlock or implement other patch exploits. + +## How does it work + +More info about mechacon flags [here](https://playstationdev.wiki/ps2devwiki/index.php/MechaCon#Region_code). Currently, Mechacon Region Code is set to 0x00130000 (bit 16, 17, 20) + region bit that matches the console or selected settings. +Patch area, that allows to play with mechacon, described [here](https://playstationdev.wiki/ps2devwiki/index.php/MechaCon#Rom_patch). This area contains sets of encrypted assembler instructions that mechacon applies to itself on console boot. +Region parameters, that are changed on slims, are described [here](https://playstationdev.wiki/ps2devwiki/index.php/MechaCon#Region_params). + +## Credits + +[Contributors](CONTRIBUTORS.md) + +### Playstation 2 models description -**Important note: If you enable force unlock every CD and DVD will be detected as a PS2 disc, meaning it breaks PS1 games and DVD-Video** +[^1]: Pre-Dragon: SCPH-1x000 - SCPH-3900x models. +[^2]: Dragon: SCPH-5xxxx - SCPH-9xxxx + PSX DESR + Sony Bravia KDL-22PX300 tvcombo. Dragon subdivided into: +[^3]: Deckard: SCPH-750xx - SCPH-900xx models + Sony Bravia KDL-22PX300 tvcombo +[^4]: Pre-Deckard: All the above: +[^5]: FAT: SCPH-5xxxx models +[^6]: DESR: PSX DVR recorders, Japan only, DESR-5xxx and DESR-7xxx. +[^7]: 70k: SCPH-700xx models diff --git a/binaries.h b/binaries.h index 7db3c71..7aa1495 100644 --- a/binaries.h +++ b/binaries.h @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +#include + extern uint8_t iomanX; extern u32 size_iomanX; @@ -56,6 +58,15 @@ extern u32 size_pwr70k; extern uint8_t pwr90k; extern u32 size_pwr90k; +extern uint8_t pwrpsx1; +extern u32 size_pwrpsx1; + +extern uint8_t pwrpsx2; +extern u32 size_pwrpsx2; + +extern uint8_t pwrtvcombo; +extern u32 size_pwrtvcombo; + extern uint8_t frame_001; extern u32 size_frame_001; diff --git a/build.sh b/build.sh deleted file mode 100644 index d14f782..0000000 --- a/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -cd irx/source/mechaproxy -make -cd - -cp irx/source/mechaproxy/irx/mechaproxy.irx irx/compiled/mechaproxy.irx - -cd irx/source/masswatcher -make -cd - -cp irx/source/masswatcher/irx/masswatcher.irx irx/compiled/masswatcher.irx - -make diff --git a/docs/ComsoftSlimFixV4/ComsoftSlimFixV4.HEX b/docs/ComsoftSlimFixV4/ComsoftSlimFixV4.HEX new file mode 100644 index 0000000..81d6435 --- /dev/null +++ b/docs/ComsoftSlimFixV4/ComsoftSlimFixV4.HEX @@ -0,0 +1,25 @@ +:020000040000FA +:100000002500400A1402E20143086F086D087308D6 +:100010006F08660874082008460849085808200830 +:1000200056083408200843086F0864086508640807 +:10003000200862087908200863086F086D087308B3 +:100040006F0866087408200861086B0861082008BA +:100050005808630861086C08690862084508720856 +:1000600020086F086E082008310839082F0830086A +:1000700032082F08320830083008350895099A09E7 +:10008000C70C0200FE0C0600670068000604040CA2 +:1000900032008709080C32006606580A0706530A20 +:1000A0008E09010C2700FA0C7E09F2024C0A7A0A2A +:1000B0000400FE0C060001024307620AE803620A1C +:1000C000010CA6010A0C320066065809F202640A05 +:1000D000C80C3200010C7E096606580A1202960FFF +:1000E00043068E09F2026A0A0A0C320066065809B3 +:1000F000F202760AF90C06002600A70A3000FA0C74 +:1001000031000400F102810AF0027F0A0008FA0CB3 +:100110007E09010CA601F202870A0008FD0C060008 +:1001200026000008FF0C0600000874007500180C7B +:100130003300000804000209B501B402F3029A0A70 +:1001400043040304350C95014307A70A0008040083 +:02015000A70AFC +:021FFE00EE0FE4 +:00000001FF diff --git a/docs/Matrix PIC/Gerber/PCB508.GM1 b/docs/Matrix PIC/Gerber/PCB508.GM1 new file mode 100644 index 0000000..e4e319a --- /dev/null +++ b/docs/Matrix PIC/Gerber/PCB508.GM1 @@ -0,0 +1,28 @@ +%FSLAX24Y24*% +%MOIN*% +G70* +G01* +G75* +%ADD10O,0.1200X0.0250*% +%ADD11R,0.1200X0.0250*% +%ADD12R,0.0512X0.0551*% +%ADD13C,0.0700*% +%ADD14C,0.1000*% +%ADD15C,0.0200*% +%ADD16C,0.0100*% +%ADD17C,0.0079*% +%ADD18O,0.1280X0.0330*% +%ADD19R,0.1280X0.0330*% +%ADD20R,0.0592X0.0631*% +%ADD21C,0.0780*% +%ADD22C,0.1080*% +D16* +X94700Y80700D02* +X101200D01* +X94700Y84200D02* +X101200D01* +Y80700D02* +Y84200D01* +X94700Y80700D02* +Y84200D01* +M02* diff --git a/docs/Matrix PIC/Gerber/PCB508.GTL b/docs/Matrix PIC/Gerber/PCB508.GTL new file mode 100644 index 0000000..9354ffd --- /dev/null +++ b/docs/Matrix PIC/Gerber/PCB508.GTL @@ -0,0 +1,85 @@ +%FSLAX24Y24*% +%MOIN*% +G70* +G01* +G75* +%ADD10O,0.1200X0.0250*% +%ADD11R,0.1200X0.0250*% +%ADD12R,0.0512X0.0551*% +%ADD13C,0.0700*% +%ADD14C,0.1000*% +%ADD15C,0.0200*% +%ADD16C,0.0100*% +D10* +X99200Y81100D02* +D03* +Y81600D02* +D03* +Y82100D02* +D03* +Y82600D02* +D03* +X96700Y81100D02* +D03* +Y81600D02* +D03* +Y82100D02* +D03* +D11* +Y82600D02* +D03* +D12* +X97500Y83600D02* +D03* +X96752D02* +D03* +D13* +X95100Y83700D02* +D03* +Y82700D02* +D03* +Y81100D02* +D03* +D14* +X100700Y83200D02* +D03* +D15* +X95100Y83700D02* +X96652D01* +X98500Y81100D02* +X99200D01* +X97600Y82000D02* +X98500Y81100D01* +X97600Y82000D02* +Y83600D01* +X95100Y81100D02* +X96700D01* +X99200Y82600D02* +Y82900D01* +X99500Y83200D01* +X100700D01* +X95200Y82600D02* +X96700D01* +X95100Y82700D02* +X95200Y82600D01* +D16* +X100300Y81100D02* +X100400D01* +Y81000D01* +Y81200D01* +Y81100D01* +X100700D01* +X100800Y81200D01* +Y81500D02* +X100200D01* +X100400Y81700D01* +X100200Y81900D01* +X100800D01* +X100300Y82200D02* +X100400D01* +Y82100D01* +Y82300D01* +Y82200D01* +X100700D01* +X100800Y82300D01* +M02* diff --git a/docs/Matrix PIC/Gerber/PCB508.GTO b/docs/Matrix PIC/Gerber/PCB508.GTO new file mode 100644 index 0000000..442b9e7 --- /dev/null +++ b/docs/Matrix PIC/Gerber/PCB508.GTO @@ -0,0 +1,85 @@ +%FSLAX24Y24*% +%MOIN*% +G70* +G01* +G75* +%ADD10O,0.1200X0.0250*% +%ADD11R,0.1200X0.0250*% +%ADD12R,0.0512X0.0551*% +%ADD13C,0.0700*% +%ADD14C,0.1000*% +%ADD15C,0.0200*% +%ADD16C,0.0100*% +%ADD17C,0.0079*% +D16* +X97825Y82850D02* +X97862Y82762D01* +X97950Y82725D01* +X98038Y82762D01* +X98075Y82850D01* +X97550Y80850D02* +Y82850D01* +Y80850D02* +X98350D01* +Y82850D01* +X98075D02* +X98350D01* +X97550D02* +X97825D01* +X95600Y81400D02* +Y80900D01* +Y81067D01* +X95933Y81400D01* +X95683Y81150D01* +X95933Y80900D01* +Y84000D02* +X95767D01* +X95850D01* +Y83583D01* +X95767Y83500D01* +X95683D01* +X95600Y83583D01* +X99033Y83417D02* +X98950Y83500D01* +X98783D01* +X98700Y83417D01* +Y83083D01* +X98783Y83000D01* +X98950D01* +X99033Y83083D01* +Y83250D01* +X98867D01* +X99200Y83000D02* +Y83500D01* +X99533Y83000D01* +Y83500D01* +X99700D02* +Y83000D01* +X99950D01* +X100033Y83083D01* +Y83417D01* +X99950Y83500D01* +X99700D01* +X95100Y82150D02* +X95433D01* +X95267Y82317D02* +Y81983D01* +X95933Y82400D02* +X95600D01* +Y82150D01* +X95766Y82233D01* +X95850D01* +X95933Y82150D01* +Y81983D01* +X95850Y81900D01* +X95683D01* +X95600Y81983D01* +D17* +X96260Y84112D02* +X97992D01* +X96260Y83088D02* +Y84112D01* +Y83088D02* +X97992D01* +Y84112D01* +M02* diff --git a/docs/Matrix PIC/Gerber/PCB508.GTS b/docs/Matrix PIC/Gerber/PCB508.GTS new file mode 100644 index 0000000..8faa96a --- /dev/null +++ b/docs/Matrix PIC/Gerber/PCB508.GTS @@ -0,0 +1,52 @@ +%FSLAX24Y24*% +%MOIN*% +G70* +G01* +G75* +%ADD10O,0.1200X0.0250*% +%ADD11R,0.1200X0.0250*% +%ADD12R,0.0512X0.0551*% +%ADD13C,0.0700*% +%ADD14C,0.1000*% +%ADD15C,0.0200*% +%ADD16C,0.0100*% +%ADD17C,0.0079*% +%ADD18O,0.1280X0.0330*% +%ADD19R,0.1280X0.0330*% +%ADD20R,0.0592X0.0631*% +%ADD21C,0.0780*% +%ADD22C,0.1080*% +D18* +X99200Y81100D02* +D03* +Y81600D02* +D03* +Y82100D02* +D03* +Y82600D02* +D03* +X96700Y81100D02* +D03* +Y81600D02* +D03* +Y82100D02* +D03* +D19* +Y82600D02* +D03* +D20* +X97500Y83600D02* +D03* +X96752D02* +D03* +D21* +X95100Y83700D02* +D03* +Y82700D02* +D03* +Y81100D02* +D03* +D22* +X100700Y83200D02* +D03* +M02* diff --git a/docs/Matrix PIC/MFIX_H16.HEX b/docs/Matrix PIC/MFIX_H16.HEX new file mode 100644 index 0000000..010d9f0 --- /dev/null +++ b/docs/Matrix PIC/MFIX_H16.HEX @@ -0,0 +1,16 @@ +:0800000000250CC000020CFF00060CFA09630CFA7C +:0800080009630CFA09630CFA096306660A2D0CFAF7 +:08001000096306660A2D0CFA096306660A2D0CFABE +:08001800096306660A2D0CFA096306660A2D0CFAB6 +:08002000096306660A2D0CFA096306660A2D0CFAAE +:08002800096306660A2D0CFA0963000406660A2DA8 +:0800300006660A2D06660A2D06660A2D06660A2D3C +:0800380006660A2D06660A2D06660A2D06660A2D34 +:0800400006660A2D0CC800320C01096306660A2DF3 +:0800480002F20A4406660A2D06660A2D06660A2D85 +:0800500006660A2D06660A2D06660A2D06660A2D1C +:0800580006660A2D06660A2D06660A2D0CFB00268A +:08006000000600040A6100300CFA0031000402F1C5 +:040068000A6602F00A640800BC +:010FFF000FEEF4 +:00000001FF diff --git a/docs/Matrix PIC/MFIX_H8.HEX b/docs/Matrix PIC/MFIX_H8.HEX new file mode 100644 index 0000000..4a351f4 --- /dev/null +++ b/docs/Matrix PIC/MFIX_H8.HEX @@ -0,0 +1,17 @@ +:100000002500C00C0200FF0C0600FA0C6309FA0C74 +:100010006309FA0C6309FA0C630966062D0AFA0CE7 +:10002000630966062D0AFA0C630966062D0AFA0CA6 +:10003000630966062D0AFA0C630966062D0AFA0C96 +:10004000630966062D0AFA0C630966062D0AFA0C86 +:10005000630966062D0AFA0C6309040066062D0A78 +:1000600066062D0A66062D0A66062D0A66062D0A04 +:1000700066062D0A66062D0A66062D0A66062D0AF4 +:1000800066062D0AC80C3200010C630966062D0AAB +:10009000F202440A66062D0A66062D0A66062D0A35 +:1000A00066062D0A66062D0A66062D0A66062D0AC4 +:1000B00066062D0A66062D0A66062D0AFB0C26002A +:1000C00006000400610A3000FA0C31000400F1025D +:1000D000660AF002640A0008FF0FFF0FFF0FFF0F10 +:080400000F000F000F000F00B8 +:021FFE00EE3FB4 +:00000001FF diff --git a/docs/Matrix PIC/MatrixFix508v2.txt b/docs/Matrix PIC/MatrixFix508v2.txt new file mode 100644 index 0000000..1124080 --- /dev/null +++ b/docs/Matrix PIC/MatrixFix508v2.txt @@ -0,0 +1,102 @@ +The Matrix Team - V12 Dead Syndrome Fix V2.0 +-------------------------------------------- + + +UPDATE : November 24, 2004 +-------------------------- + +Added hex file in INHEX8 for those programmers that don't support INHEX16. + +Settings are included in the .hex file but can be set manually as +follows : IntRC oscillator, Internal MCLR, Watchdog timer ON. + +Note : If you want to make sure that your pic was programmed correctly and +that the resistor value is low enough to turn off your pstwo you can do so +in the following way : Install the 12c508 as from the schematics but connect +pin 4 to GND instead of point K. The pstwo should turn on when pressing reset +and turn itself off after three seconds. If this happens you can be sure that +the 12c508 is working and that the resistor value chosen is correct. +Disconnect pin 4 from GND and connect it to point K on the diagrams and you +are set to go. + + +November 22, 2004 +----------------- + +Just a quick follow-up to our previous reports. A more in depth explanation +will follow later on but at this point we believe it's more important to +offer a quick fix for all those poor pstwos out there ;-) + +Further analysis on several V12 has shown that in certain situations the +mechanics controller can fail while communicating with the dvd controller. +You can notice when this happens since the reset button, which is connected +to the mechanics controller, will stop responding and the only way to turn +off the machine is to unplug the power jack. + +When the mechanics controller crashes, the dvd controller keeps sending +a pulse train to the tracking and focus drivers which results in a steady +voltage increase on both the tracking and the focus coils. +With the proposed diode fix, this increase is initially limited but if the +user leaves the crashed pstwo on for several seconds the output drivers +will eventually reach saturation and, if the RS2004FS thermal protection +doesn't kick in, the coils can burn from the increased current flowing. + +As promised on our latest news, our proposed solution to this problem +consists in a simple 12c508 plus an additional resistor. + +There are certainly other solutions to this problems (some of which are +currently being tested) which can offer a more general protection +to the coils by constantly monitoring the voltage applied to them. +However we felt that it was much more important to offer a cheap, +easy and fast fix instead of a more general one which would be outside +the reach of the general hobbyist. +In a few words : programming a 12c508 pic is something most people +with interest in electronics can easily do. The blank component is +very cheap (around 1 USD) and a programmer can be built or bought for +a few bucks if needed. + +Further more, this simple fix has been proven to work an all occasions +during our tests, so it should already offer a very high protection. + +We are releasing the pic hex file free (as in speech and as in beer ;) +for all to use and experiment on. We are also releasing the gerber +files for two small PCBs : one can be used with only the pic and the +resistor, while the other has also space for 8 1n4148 smd diodes. +Do with those as you wish : make a few of them for you own use, or +build some more and offer them for sale (hopefully for a low price, +since all the research and development cost has been already done ;-). + + +The simple program to be burned inside the 12c508 will constantly +monitor the communication between the mechanics controller and +the dvd controller. As soon as it detects a crash in the communication +it will turn off the pstwo to avoid any possibile damage to the coils. + +Important note : the resistor value (1500 Ohm) has been chosen as the +best value according to our tests. +If the value is less than 1000ohm the pstwo will stay in a permanent +reset state and not even the red led will turn on. +On the other end if the value is higher than 3300 ohms the pic will not +be able to turn off the pstwo when needed. This has been tested on +several machines with consistent behaviour. +However there might be other board revisions which might behave in +a different way (maybe because of a different reset controller IC used). + +So if you experience problems with the 1500 Ohm resistor, you can probably +safely increase it to 2000/2200 ohms. Please, only experiment with +different values if you understand what has been said (or if you don't +care about running your pstwo without being sure that the coils protection +is working). + +The usual installation care should be used when installing this fix. +Preferred position for placing the pic or the PCB is in the lower left +corner of the ps2 motherboard. Make sure that both a J and K wires run +parallel to the board and make them as short as possible. + + +Last words : this fix can be used with or without the diode fix. +The diode fix can certainly increase the life span of your lens, and +should provide you with more time to realize that your ps2 crashed and +turn off the main power, should the pic chip fail to work. This has +not happened once so far in our test, but as usual the real results +will come from the thousands of pstwos out there. diff --git a/docs/PICfix.md b/docs/PICfix.md new file mode 100644 index 0000000..04a9d95 --- /dev/null +++ b/docs/PICfix.md @@ -0,0 +1,53 @@ +# PIC fix + +Note: seems subzero mode also can save from DSP crash. + +All FAT and some 70k models are affected by the DSP bug and need hardware fix to avoid frying. + +In 2004 the Matrix team developed the so-called "PIC fix". It consists of PIC12C508 (SOIC chips, it's important, dont use MSOP chips) and a resistor 1.5kOhm or 2.2kOhm (resistance depends on your system). PIC12C508 should be programmed with shipped `MFIX_H8.HEX` or `MFIX_H16.HEX` firmware file. Details on how to program this chip aren't covered here. Optionally, you can use Gerber developed board. Also, you can use a [PCB board](https://oshpark.com/shared_projects/3D5p1xeY) developed for Comsoft fix but also suitable for Matrix PIC fix. For experiments, there is also a Comsoft v4 firmware file, however, it is not tested. Note, that the Matrix team Readme is kept there for reference. There is no need to apply the so-called "diode fix" - per our investigations it is useless. + +## Board revisions + +Historically, hackers use board naming based on versioning, like v10, while sony uses either chassis or Mainboard model. Below is the table for our needs: + +| Unofficial version | Chassis | Mainboard | +|---|---|---| +| v9 | H-chassis, 50k | GH-023 | +| v10 | I-chassis, 50k | GH-026 | +| v11 | J-chassis, 50k | GH-029 | +| v12 | K-chassis, 70k | GH-032/GH-035 | +| v13 | K-chassis, 70k | GH-032/GH-035 | + +### FAT 50k + +Chassis can be recognized by different methods. The safest, by the DVD player version. In the PS2 browser press Triangle and check the DVD Player version: + +- 3.00 this is H-chassis (v9) +- 3.02 this is I-chassis (v10) +- 3.03/3.04 this is J-chassis (v11) + +It is also possible to recognize Chassis by sticker, but be careful, a case can be replaced, so data may be inaccurate. But this can at least help when you are buying a console and can get only photos of them. + +- if there is a single `J` letter (for example `J SZMT`) - this is J-chassis (v11) +- if there is a single `I` letter (for example `I SKD`) - this is I-chassis (v10) +- if there is a single `H` letter (for example `H FOXC`) or if there are no single letters `H`, `I` or `J` at all - this is H-chassis (v9) + +Below 2 diagrams for v9 and v10. The v11 diagram is missing but it should be the same as v10. +![v9_picfix_diagram](v9_picfix_diagram.jpg) +![v10_picfix_diagram](v10_picfix_diagram.jpg) + +### Slim 70k + +70k is much harder to differentiate. It has 2 major board revisions: GH-035-xx (for combined EE+GS chip) and GH-032-xx (for separate EE and GS). Both boards can be with and without Sony fix. Looks like the easiest way to check this without an opening console, check your mechacon version. Version 6.04 have the fix on the board, while 6.00 and 6.02 doesnt have the fix. + +Below diagram for 70k. +![v12_picfix_diagram](v12_picfix_diagram.jpg) + +## Credits + +ModzvilleUSA for actual resistor values and testing them on FATs. HaloSlayer255 for researches. + +## Sources + +- +- diff --git a/docs/reversings.txt b/docs/reversings.txt new file mode 100644 index 0000000..d4d0762 --- /dev/null +++ b/docs/reversings.txt @@ -0,0 +1,50 @@ +Dragon NVRAM has 2 encrypted areas: +region area at offset 0x1C6 +patch area at offset 0x320 + +region area consists of 2 10-byte blocks. Last 2 bytes in each block - checksum. 1st checksum byte is useless and skipped during decryption. +First 8byte block - random value used for encrypting the second block. Can be anything. +The second block consists of 2 parts - a random 2-byte block, and a 6-byte block containing region falgs. A random 2-byte block can be of anything. +6-byte block bit flags are described on PSX dev wiki. In short - the highest byte contains 8 possible classic regions (from Japan to Mexico). +On all models is set only exactly one bitflag is in the highest byte, so only one region is assigned (with the only exception - Review Kit). +2nd byte purpose is unknown - always all bits are cleared (except Review Kit: all bits are set). +3rd byte contains ps2 types and the main mechapwn flag allowing you to change console type to the arcade, prototype, dtl, semi-dtl, etc. +4-6 byte purpose unknown - always all bits cleared. + +The Patch area contains 2 blocks 112 bytes long. Last 2 bytes in each block - checksum. 1st checksum byte is useless and skipped during decryption. +After decryption these 2 blocks combined in one block: 216 bytes long (2 x 108) +This block structure: +struct rom_patch +{ + uint32_t address[4]; + uint32_t value[4]; + uint32_t svc_address[4]; + uint8_t payload[168]; + uint32_t crc; +}; + +First 16 bytes - 4 addresses inside mechacon rom that should be patched, next 16 bytes - 4 values that are written over at those addresses. +If the address is zero, then the patch is skipped. +Next 16 bytes - 4 svc_addresses (TODO: describe what that means) +The rest is for payload (168 bytes) and checksum (TODO: provide more information about payload) + +The current Force Unlock implementation uses 2 patches. All Sony retail patches (except PSX1 5.10 and 6.02 ver b used in 70k) use a maximum 2 patches, so there is space for 2 patches: +5.00 0000B4F0 48492701 0000B630 484B2701 +5.02 0000B6CC 250E2701 0000B82C F0002701 +5.04 0000B6E0 250E2701 0000B840 F0002701 +5.06 0000B6E0 250E2701 0000B840 F0002701 +5.06MX 0000B6B4 250E2701 0000B814 F0002701 +5.12 0000B6FC 250E2701 0000B85C F0002701 +6.00 0000B280 250E2701 0000B3E0 F0002701 +6.02 0000B3C8 250E2700 0000B53C F0002700 +6.04 0000B6C0 250E2700 0000B834 F0002700 +6.06 0000B804 250E2700 0000B978 F0002700 +6.10 0000B868 250E2700 0000B9DC F0002700 +6.12 0000B7F8 250E2700 0000B96C F0002700 +TODO: explain what exactly Force Unlock is patching. + +PSX doesn't need force unlock. +For 6.02 original ver b patch gets rewritten to free up patch addresses. The original 4-patch set is lowered to a 1-patch set. +TODO: provide source code for 6.02 rewritten payload. + +6.00 and 6.02 mechacon firmware contains a bug: DVDVideo disk stop working if the DTL flag is set. diff --git a/docs/v10_picfix_diagram.jpg b/docs/v10_picfix_diagram.jpg new file mode 100644 index 0000000..8069e2c Binary files /dev/null and b/docs/v10_picfix_diagram.jpg differ diff --git a/docs/v12_picfix_diagram.jpg b/docs/v12_picfix_diagram.jpg new file mode 100644 index 0000000..29d74e7 Binary files /dev/null and b/docs/v12_picfix_diagram.jpg differ diff --git a/docs/v9_picfix_diagram.jpg b/docs/v9_picfix_diagram.jpg new file mode 100644 index 0000000..3bf62a0 Binary files /dev/null and b/docs/v9_picfix_diagram.jpg differ diff --git a/exploit.c b/exploit.c index c126d37..f8f7608 100644 --- a/exploit.c +++ b/exploit.c @@ -18,917 +18,953 @@ #include #include "mecha.h" +#include "exploit.h" -static const uint8_t date500[] = { 0x03, 0x01, 0x20, 0x15, 0x28 }; // 5.00 (CXR706080-101GG) $Date: 03/01/20 15:28 $ 0x12CBC -static const uint8_t date502[] = { 0x03, 0x03, 0x05, 0x22, 0x40 }; // 5.02 (CXR706080-102GG) $Date: 03/03/05 22:40 $ 0x1316C -static const uint8_t date504[] = { 0x03, 0x04, 0x08, 0x23, 0x27 }; // 5.04 (CXR706080-103GG) $Date: 03/04/08 23:27 $ 0x132A8 -static const uint8_t date506[] = { 0x03, 0x06, 0x25, 0x23, 0x03 }; // 5.06 (CXR706080-104GG) $Date: 03/06/25 23:03 $ 0x132A8 -static const uint8_t date506mx[] = { 0x04, 0x04, 0x06, 0x13, 0x05 }; // 5.06MX (CXR706080-106GG) $Date: 04/04/06 13:05 $ 0x13280 -static const uint8_t date510[] = { 0x03, 0x10, 0x08, 0x22, 0x00 }; // 5.10 (CXR706080-702GG) $Date: 03/10/08 22:00 $ 0x16370 -static const uint8_t date512[] = { 0x03, 0x11, 0x20, 0x20, 0x05 }; // 5.12 (CXR706080-105GG) $Date: 03/11/20 20:05 $ 0x13818 -static const uint8_t date514[] = { 0x04, 0x08, 0x25, 0x02, 0x12 }; // 5.14 (CXR706080-703GG) $Date: 2004/08/25 02:12:23 $ 0x18354 -static const uint8_t date600[] = { 0x04, 0x06, 0x21, 0x09, 0x53 }; // 6.00 (CXR716080-101GG) $Date: 2004/06/21 09:53:52 $ 0x132C8 -static const uint8_t date602[] = { 0x04, 0x07, 0x20, 0x09, 0x04 }; // 6.02 (CXR716080-102GG) $Date: 2004/07/20 09:04:01 $ 0x134A8 -static const uint8_t date604[] = { 0x04, 0x12, 0x10, 0x01, 0x30 }; // 6.04 (CXR716080-103GG) $Date: 2004/12/10 01:30:29 $ 0x13848 -static const uint8_t date606[] = { 0x05, 0x04, 0x27, 0x09, 0x17 }; // 6.06 (CXR716080-104GG) $Date: 2005/04/27 09:17:37 $ 0x1398C -static const uint8_t date610[] = { 0x06, 0x03, 0x29, 0x06, 0x48 }; // 6.10 (CXR716080-106GG) $Date: 2006/03/29 06:48:21 $ 0x13A0C -static const uint8_t date612[] = { 0x07, 0x01, 0x29, 0x03, 0x47 }; // 6.12 (CXR726080-301GB) $Date: 2007/01/29 03:47:05 $ 0x139C4 +static const uint8_t date500[] = {0x03, 0x01, 0x20, 0x15, 0x28}; // 5.00 (CXR706080-101GG) $Date: 03/01/20 15:28 $ 0x12CBC +static const uint8_t date502[] = {0x03, 0x03, 0x05, 0x22, 0x40}; // 5.02 (CXR706080-102GG) $Date: 03/03/05 22:40 $ 0x1316C +static const uint8_t date504[] = {0x03, 0x04, 0x08, 0x23, 0x27}; // 5.04 (CXR706080-103GG) $Date: 03/04/08 23:27 $ 0x132A8 +static const uint8_t date506[] = {0x03, 0x06, 0x25, 0x23, 0x03}; // 5.06 (CXR706080-104GG) $Date: 03/06/25 23:03 $ 0x132A8 +static const uint8_t date506mx[] = {0x04, 0x04, 0x06, 0x13, 0x05}; // 5.06MX (CXR706080-106GG) $Date: 04/04/06 13:05 $ 0x13280 +static const uint8_t date510[] = {0x03, 0x10, 0x08, 0x22, 0x00}; // 5.10 (CXR706080-702GG) $Date: 03/10/08 22:00 $ 0x16370 +static const uint8_t date512[] = {0x03, 0x11, 0x20, 0x20, 0x05}; // 5.12 (CXR706080-105GG) $Date: 03/11/20 20:05 $ 0x13818 +static const uint8_t date514[] = {0x04, 0x08, 0x25, 0x02, 0x12}; // 5.14 (CXR706080-703GG) $Date: 2004/08/25 02:12:23 $ 0x18354 +static const uint8_t date600[] = {0x04, 0x06, 0x21, 0x09, 0x53}; // 6.00 (CXR716080-101GG) $Date: 2004/06/21 09:53:52 $ 0x132C8 +static const uint8_t date602[] = {0x04, 0x07, 0x20, 0x09, 0x04}; // 6.02 (CXR716080-102GG) $Date: 2004/07/20 09:04:01 $ 0x134A8 +static const uint8_t date604[] = {0x04, 0x12, 0x10, 0x01, 0x30}; // 6.04 (CXR716080-103GG) $Date: 2004/12/10 01:30:29 $ 0x13848 +static const uint8_t date606[] = {0x05, 0x04, 0x27, 0x09, 0x17}; // 6.06 (CXR716080-104GG) $Date: 2005/04/27 09:17:37 $ 0x1398C +static const uint8_t date610[] = {0x06, 0x03, 0x29, 0x06, 0x48}; // 6.10 (CXR716080-106GG) $Date: 2006/03/29 06:48:21 $ 0x13A0C +static const uint8_t date612[] = {0x07, 0x01, 0x29, 0x03, 0x47}; // 6.12 (CXR726080-301GB) $Date: 2007/01/29 03:47:05 $ 0x139C4 +// clang-format off static const uint8_t patch500[] = { - 0xA4, 0x2E, 0xC7, 0x05, 0x5A, 0x7C, 0x83, 0xDB, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xCF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xE2, 0x51, 0x4B, 0xA7, 0xB5, 0xDA, + 0xA4, 0x2E, 0xC7, 0x05, 0x5A, 0x7C, 0x83, 0xDB, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xCF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE2, 0x51, 0x4B, 0xA7, 0xB5, 0xDA, }; static const uint8_t patch502[] = { - 0x5D, 0x7A, 0x17, 0x81, 0xD8, 0xE5, 0x2A, 0xFE, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0xCB, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x58, 0x2E, 0x90, 0x7D, 0xD9, 0x6C, + 0x5D, 0x7A, 0x17, 0x81, 0xD8, 0xE5, 0x2A, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0xCB, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x58, 0x2E, 0x90, 0x7D, 0xD9, 0x6C, }; static const uint8_t patch504[] = { - 0xD6, 0xC3, 0x55, 0xE0, 0x9E, 0xBD, 0x1F, 0x59, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, - 0x34, 0x6A, 0xC1, 0xD1, 0x31, 0xE8, 0xD5, 0xAB, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x2B, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xCC, 0xB9, 0xA7, 0x0A, 0x93, 0xC9, + 0xD6, 0xC3, 0x55, 0xE0, 0x9E, 0xBD, 0x1F, 0x59, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, + 0x34, 0x6A, 0xC1, 0xD1, 0x31, 0xE8, 0xD5, 0xAB, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x2B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xCC, 0xB9, 0xA7, 0x0A, 0x93, 0xC9, }; static const uint8_t patch506[] = { - 0xD6, 0xC3, 0x55, 0xE0, 0x9E, 0xBD, 0x1F, 0x59, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xCC, 0xB9, 0xA7, 0x0A, 0x93, 0xC9, + 0xD6, 0xC3, 0x55, 0xE0, 0x9E, 0xBD, 0x1F, 0x59, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xCC, 0xB9, 0xA7, 0x0A, 0x93, 0xC9, }; static const uint8_t patch506mx[] = { - 0x35, 0x9F, 0x7B, 0x6E, 0xCC, 0x32, 0xCE, 0x6F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xDD, 0x64, 0x01, 0xDA, 0xC7, 0xE3, + 0x35, 0x9F, 0x7B, 0x6E, 0xCC, 0x32, 0xCE, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xDD, 0x64, 0x01, 0xDA, 0xC7, 0xE3, }; static const uint8_t patch510[] = { - 0xF9, 0xDB, 0x05, 0x69, 0x93, 0xC6, 0x56, 0xD0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xF1, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xAE, 0x88, 0xD7, 0xDE, 0x29, 0x14, + 0xF9, 0xDB, 0x05, 0x69, 0x93, 0xC6, 0x56, 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xF1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xAE, 0x88, 0xD7, 0xDE, 0x29, 0x14, }; static const uint8_t patch512[] = { - 0x2B, 0xF1, 0x4D, 0xE5, 0xF4, 0x92, 0x8B, 0x69, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0xE3, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xBA, 0xBA, 0x17, 0x19, 0xB7, 0x5B, + 0x2B, 0xF1, 0x4D, 0xE5, 0xF4, 0x92, 0x8B, 0x69, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0xE3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xBA, 0xBA, 0x17, 0x19, 0xB7, 0x5B, }; static const uint8_t patch514[] = { - 0x6C, 0xF8, 0x21, 0x82, 0x88, 0xFF, 0x73, 0x6D, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x97, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xA9, 0x86, 0x80, 0x73, 0xBB, 0xDD, + 0x6C, 0xF8, 0x21, 0x82, 0x88, 0xFF, 0x73, 0x6D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x97, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA9, 0x86, 0x80, 0x73, 0xBB, 0xDD, }; static const uint8_t patch600[] = { - 0x32, 0x7D, 0x74, 0x49, 0x0A, 0xFC, 0x61, 0x81, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0xCB, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xFC, 0x2C, 0x90, 0x7D, 0x95, 0xCA, + 0x32, 0x7D, 0x74, 0x49, 0x0A, 0xFC, 0x61, 0x81, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0xCB, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0x2C, 0x90, 0x7D, 0x95, 0xCA, }; static const uint8_t patch602[] = { - 0xB3, 0x53, 0xCC, 0x92, 0xD6, 0xFE, 0xA9, 0x1A, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x7D, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x58, 0xDB, 0x2A, 0x79, 0x3C, + 0xB3, 0x53, 0xCC, 0x92, 0xD6, 0xFE, 0xA9, 0x1A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x7D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x58, 0xDB, 0x2A, 0x79, 0x3C, }; static const uint8_t patch604[] = { - 0x65, 0xA4, 0xD0, 0x82, 0xF5, 0x44, 0x5D, 0xFD, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x97, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xE5, 0x6C, 0x41, 0x71, 0xF9, 0xFC, + 0x65, 0xA4, 0xD0, 0x82, 0xF5, 0x44, 0x5D, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x97, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE5, 0x6C, 0x41, 0x71, 0xF9, 0xFC, }; static const uint8_t patch606[] = { - 0x9D, 0x6A, 0xCB, 0x36, 0x24, 0x9A, 0x76, 0xC4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x73, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x49, 0xDA, 0x5A, 0x26, 0xB9, 0x5C, + 0x9D, 0x6A, 0xCB, 0x36, 0x24, 0x9A, 0x76, 0xC4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x49, 0xDA, 0x5A, 0x26, 0xB9, 0x5C, }; static const uint8_t patch610[] = { - 0x8A, 0x94, 0xDC, 0xF4, 0x71, 0x25, 0xE4, 0x64, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x55, 0xD8, 0xBE, 0xD8, 0x79, 0x3C, + 0x8A, 0x94, 0xDC, 0xF4, 0x71, 0x25, 0xE4, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0xD8, 0xBE, 0xD8, 0x79, 0x3C, }; static const uint8_t patch612[] = { - 0x54, 0x35, 0xA0, 0xAB, 0x8E, 0x5E, 0xF9, 0x3E, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, - 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xE0, 0xFC, 0x39, 0xA0, 0x95, 0x4A, + 0x54, 0x35, 0xA0, 0xAB, 0x8E, 0x5E, 0xF9, 0x3E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, + 0x38, 0xE1, 0x42, 0xF1, 0x86, 0x04, 0x3C, 0xB4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0xFC, 0x39, 0xA0, 0x95, 0x4A, }; -const uint8_t *getPatch(uint8_t *build_date) -{ - if (memcmp(build_date, date500, 5) == 0) - return patch500; - else if (memcmp(build_date, date502, 5) == 0) - return patch502; - else if (memcmp(build_date, date504, 5) == 0) - return patch504; - else if (memcmp(build_date, date506, 5) == 0) - return patch506; - else if (memcmp(build_date, date506mx, 5) == 0) - return patch506mx; - else if (memcmp(build_date, date510, 5) == 0) - return patch510; - else if (memcmp(build_date, date512, 5) == 0) - return patch512; - else if (memcmp(build_date, date514, 5) == 0) - return patch514; - else if (memcmp(build_date, date600, 5) == 0) - return patch600; - else if (memcmp(build_date, date602, 5) == 0) - return patch602; - else if (memcmp(build_date, date604, 5) == 0) - return patch604; - else if (memcmp(build_date, date606, 5) == 0) - return patch606; - else if (memcmp(build_date, date610, 5) == 0) - return patch610; - else if (memcmp(build_date, date612, 5) == 0) - return patch612; - - return 0; -} - static const uint8_t forceunlock500[] = { - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0xbb, 0x97, 0xd9, 0xda, 0x5f, 0xf3, 0xf2, 0xc2, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x52, 0x93, 0xeb, 0x18, 0xd8, 0xb8, 0x78, 0x24, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0xc7, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0xdf, 0x94, 0xfe, 0xff, 0x00, 0x4a, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0xbb, 0x97, 0xd9, 0xda, 0x5f, 0xf3, 0xf2, 0xc2, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x52, 0x93, 0xeb, 0x18, 0xd8, 0xb8, 0x78, 0x24, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0xc7, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0xdf, 0x94, 0xfe, 0xff, 0x00, 0x4a, }; static const uint8_t forceunlock502[] = { - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0xc0, 0xb5, 0x2c, 0x29, 0x11, 0x56, 0x52, 0x9a, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0xa1, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x07, 0x91, 0xfe, 0xff, 0x00, 0x25, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0xc0, 0xb5, 0x2c, 0x29, 0x11, 0x56, 0x52, 0x9a, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0xa1, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x07, 0x91, 0xfe, 0xff, 0x00, 0x25, }; static const uint8_t forceunlock504[] = { - 0xb1, 0xea, 0x8b, 0xc0, 0xc8, 0x19, 0x84, 0x35, - 0x25, 0x75, 0xde, 0x2e, 0x26, 0xc9, 0x24, 0xae, - 0xa6, 0x84, 0x83, 0x24, 0xdd, 0xf6, 0x9a, 0xeb, - 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, - 0x61, 0x7d, 0x23, 0xa3, 0x51, 0x05, 0x4e, 0x8c, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x2e, 0xa7, 0xea, 0x33, 0x14, 0xad, 0x99, 0xd4, - 0x5d, 0xa6, 0x0d, 0xcc, 0xd7, 0x1b, 0x3d, 0x78, - 0xcb, 0x27, 0x51, 0xb4, 0x85, 0x40, 0xf0, 0x96, - 0xb6, 0xda, 0xef, 0x69, 0x9d, 0x96, 0x4b, 0x9c, - 0x95, 0x6d, 0x23, 0xa4, 0xe1, 0x23, 0x57, 0x1c, - 0xce, 0x8e, 0xd3, 0x2f, 0x1c, 0xc6, 0x55, 0x4b, - 0xcd, 0xfb, 0x5a, 0xef, 0xd3, 0x9b, 0x3a, 0xd8, - 0xb4, 0x89, 0x9c, 0xb7, 0x72, 0x97, 0x00, 0xb4, - 0xba, 0xdf, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xe6, 0xe8, 0x74, 0xdf, 0x39, 0xd0, 0xd5, 0x17, - 0x88, 0xcc, 0xb0, 0x1b, 0x75, 0x1b, 0x05, 0xa5, - 0xd6, 0x21, 0xb0, 0x70, 0xd9, 0xa5, 0x76, 0x8b, - 0x24, 0xb6, 0x09, 0x0c, 0x65, 0x47, 0xf1, 0x05, - 0x7c, 0xd2, 0xb1, 0x82, 0x87, 0xff, 0x3d, 0xa3, - 0xfc, 0xed, 0x98, 0x4b, 0x96, 0x4f, 0xf8, 0x3f, - 0x32, 0x7c, 0xfa, 0x38, 0x6b, 0x13, 0xc7, 0x69, - 0x9a, 0x24, 0xb3, 0x75, 0x64, 0xc2, 0x39, 0x65, - 0x2d, 0x43, 0x2c, 0x30, 0x15, 0x3d, 0x01, 0xb2, - 0x7d, 0x34, 0x64, 0x66, 0x1f, 0x67, 0x50, 0x20, - 0xc8, 0xb4, 0x13, 0xbd, 0xc9, 0x30, 0x98, 0xfe, - 0xe2, 0xe7, 0x23, 0x07, 0x3e, 0x3a, 0x51, 0xd2, - 0xff, 0x90, 0x97, 0x0b, 0xfc, 0xff, 0x00, 0x73, + 0xb1, 0xea, 0x8b, 0xc0, 0xc8, 0x19, 0x84, 0x35, + 0x25, 0x75, 0xde, 0x2e, 0x26, 0xc9, 0x24, 0xae, + 0xa6, 0x84, 0x83, 0x24, 0xdd, 0xf6, 0x9a, 0xeb, + 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, + 0x61, 0x7d, 0x23, 0xa3, 0x51, 0x05, 0x4e, 0x8c, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x2e, 0xa7, 0xea, 0x33, 0x14, 0xad, 0x99, 0xd4, + 0x5d, 0xa6, 0x0d, 0xcc, 0xd7, 0x1b, 0x3d, 0x78, + 0xcb, 0x27, 0x51, 0xb4, 0x85, 0x40, 0xf0, 0x96, + 0xb6, 0xda, 0xef, 0x69, 0x9d, 0x96, 0x4b, 0x9c, + 0x95, 0x6d, 0x23, 0xa4, 0xe1, 0x23, 0x57, 0x1c, + 0xce, 0x8e, 0xd3, 0x2f, 0x1c, 0xc6, 0x55, 0x4b, + 0xcd, 0xfb, 0x5a, 0xef, 0xd3, 0x9b, 0x3a, 0xd8, + 0xb4, 0x89, 0x9c, 0xb7, 0x72, 0x97, 0x00, 0xb4, + 0xba, 0xdf, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xe6, 0xe8, 0x74, 0xdf, 0x39, 0xd0, 0xd5, 0x17, + 0x88, 0xcc, 0xb0, 0x1b, 0x75, 0x1b, 0x05, 0xa5, + 0xd6, 0x21, 0xb0, 0x70, 0xd9, 0xa5, 0x76, 0x8b, + 0x24, 0xb6, 0x09, 0x0c, 0x65, 0x47, 0xf1, 0x05, + 0x7c, 0xd2, 0xb1, 0x82, 0x87, 0xff, 0x3d, 0xa3, + 0xfc, 0xed, 0x98, 0x4b, 0x96, 0x4f, 0xf8, 0x3f, + 0x32, 0x7c, 0xfa, 0x38, 0x6b, 0x13, 0xc7, 0x69, + 0x9a, 0x24, 0xb3, 0x75, 0x64, 0xc2, 0x39, 0x65, + 0x2d, 0x43, 0x2c, 0x30, 0x15, 0x3d, 0x01, 0xb2, + 0x7d, 0x34, 0x64, 0x66, 0x1f, 0x67, 0x50, 0x20, + 0xc8, 0xb4, 0x13, 0xbd, 0xc9, 0x30, 0x98, 0xfe, + 0xe2, 0xe7, 0x23, 0x07, 0x3e, 0x3a, 0x51, 0xd2, + 0xff, 0x90, 0x97, 0x0b, 0xfc, 0xff, 0x00, 0x73, }; static const uint8_t forceunlock506[] = { - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x25, 0x75, 0xde, 0x2e, 0x26, 0xc9, 0x24, 0xae, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0x57, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0xdf, 0x90, 0xfe, 0xff, 0x00, 0x4e, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x25, 0x75, 0xde, 0x2e, 0x26, 0xc9, 0x24, 0xae, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0x57, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0xdf, 0x90, 0xfe, 0xff, 0x00, 0x4e, }; static const uint8_t forceunlock506mx[] = { - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x27, 0xb7, 0x8c, 0xfa, 0x3d, 0x36, 0x03, 0xa4, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0x40, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x37, 0x91, 0xfe, 0xff, 0x00, 0xf5, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x27, 0xb7, 0x8c, 0xfa, 0x3d, 0x36, 0x03, 0xa4, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0x40, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x37, 0x91, 0xfe, 0xff, 0x00, 0xf5, }; static const uint8_t forceunlock512[] = { - 0x93, 0x85, 0x9a, 0xf5, 0x2b, 0x5b, 0xd1, 0xbd, - 0x06, 0xd7, 0x3d, 0xf7, 0x18, 0xc1, 0x8e, 0xe4, - 0x49, 0x9a, 0xe4, 0xaa, 0xe1, 0x5e, 0x67, 0x75, - 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, - 0xde, 0xa6, 0x9b, 0xe9, 0xd1, 0xd8, 0x45, 0x61, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0xe1, 0xfd, 0x79, 0xcb, 0x33, 0xb3, 0x1c, 0x78, - 0x53, 0xfd, 0x10, 0x86, 0x6c, 0x11, 0x4a, 0x3e, - 0xa3, 0xde, 0x31, 0xbf, 0xd9, 0x23, 0xc1, 0x3d, - 0x8c, 0x5d, 0x05, 0x0d, 0xbf, 0x98, 0x8f, 0x51, - 0x24, 0x0e, 0xb8, 0x08, 0xb5, 0x3c, 0x6a, 0x46, - 0xf0, 0xa7, 0x2e, 0xcf, 0x42, 0xab, 0x24, 0x25, - 0x09, 0xb4, 0x0e, 0x80, 0xf1, 0xad, 0xbe, 0x68, - 0x42, 0x80, 0xbe, 0x7e, 0x6a, 0x27, 0x00, 0xb0, - 0xfc, 0xf3, 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, - 0x27, 0x06, 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, - 0x6f, 0x74, 0xa3, 0x45, 0x18, 0x65, 0x26, 0x2b, - 0x63, 0x1f, 0xe6, 0x28, 0x37, 0x1c, 0x58, 0xc9, - 0x42, 0xd0, 0x90, 0xad, 0xe9, 0x54, 0x50, 0x4c, - 0x00, 0x57, 0x56, 0x84, 0x68, 0xca, 0x24, 0xfe, - 0x58, 0x11, 0xb6, 0x42, 0xcd, 0x79, 0xda, 0x8e, - 0x9f, 0x8c, 0x60, 0xa4, 0xc0, 0xf9, 0x51, 0x3e, - 0x3a, 0xaa, 0x10, 0x17, 0x33, 0xe8, 0x32, 0x4b, - 0xe4, 0x26, 0xc8, 0x22, 0x7b, 0xb5, 0xe5, 0x97, - 0x82, 0xbb, 0x44, 0xee, 0xb4, 0xfa, 0x66, 0xd8, - 0xd9, 0x06, 0x63, 0x97, 0x97, 0xd5, 0x21, 0x07, - 0x27, 0x1b, 0x9c, 0x53, 0x81, 0xe1, 0x65, 0x71, - 0xec, 0x7c, 0x0b, 0xf7, 0xfc, 0xff, 0x00, 0x18, + 0x93, 0x85, 0x9a, 0xf5, 0x2b, 0x5b, 0xd1, 0xbd, + 0x06, 0xd7, 0x3d, 0xf7, 0x18, 0xc1, 0x8e, 0xe4, + 0x49, 0x9a, 0xe4, 0xaa, 0xe1, 0x5e, 0x67, 0x75, + 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, + 0xde, 0xa6, 0x9b, 0xe9, 0xd1, 0xd8, 0x45, 0x61, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0xe1, 0xfd, 0x79, 0xcb, 0x33, 0xb3, 0x1c, 0x78, + 0x53, 0xfd, 0x10, 0x86, 0x6c, 0x11, 0x4a, 0x3e, + 0xa3, 0xde, 0x31, 0xbf, 0xd9, 0x23, 0xc1, 0x3d, + 0x8c, 0x5d, 0x05, 0x0d, 0xbf, 0x98, 0x8f, 0x51, + 0x24, 0x0e, 0xb8, 0x08, 0xb5, 0x3c, 0x6a, 0x46, + 0xf0, 0xa7, 0x2e, 0xcf, 0x42, 0xab, 0x24, 0x25, + 0x09, 0xb4, 0x0e, 0x80, 0xf1, 0xad, 0xbe, 0x68, + 0x42, 0x80, 0xbe, 0x7e, 0x6a, 0x27, 0x00, 0xb0, + 0xfc, 0xf3, 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, + 0x27, 0x06, 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, + 0x6f, 0x74, 0xa3, 0x45, 0x18, 0x65, 0x26, 0x2b, + 0x63, 0x1f, 0xe6, 0x28, 0x37, 0x1c, 0x58, 0xc9, + 0x42, 0xd0, 0x90, 0xad, 0xe9, 0x54, 0x50, 0x4c, + 0x00, 0x57, 0x56, 0x84, 0x68, 0xca, 0x24, 0xfe, + 0x58, 0x11, 0xb6, 0x42, 0xcd, 0x79, 0xda, 0x8e, + 0x9f, 0x8c, 0x60, 0xa4, 0xc0, 0xf9, 0x51, 0x3e, + 0x3a, 0xaa, 0x10, 0x17, 0x33, 0xe8, 0x32, 0x4b, + 0xe4, 0x26, 0xc8, 0x22, 0x7b, 0xb5, 0xe5, 0x97, + 0x82, 0xbb, 0x44, 0xee, 0xb4, 0xfa, 0x66, 0xd8, + 0xd9, 0x06, 0x63, 0x97, 0x97, 0xd5, 0x21, 0x07, + 0x27, 0x1b, 0x9c, 0x53, 0x81, 0xe1, 0x65, 0x71, + 0xec, 0x7c, 0x0b, 0xf7, 0xfc, 0xff, 0x00, 0x18, }; static const uint8_t forceunlock600[] = { - 0x4d, 0xa2, 0x75, 0x84, 0x97, 0x31, 0x0b, 0x48, - 0x68, 0x8e, 0x58, 0x03, 0x40, 0xa1, 0x72, 0x8a, - 0x00, 0x08, 0x3d, 0x86, 0x52, 0xe1, 0x0f, 0x19, - 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x99, 0x8d, 0x68, 0x58, 0x75, 0x96, 0x92, 0x46, - 0x1f, 0xc5, 0x2b, 0xbb, 0x6a, 0x31, 0x07, 0x5d, - 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, 0x27, 0x06, - 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, 0x6f, 0x74, - 0xa3, 0x45, 0x18, 0x65, 0x26, 0x2b, 0x63, 0x1f, - 0xe6, 0x28, 0x37, 0x1c, 0x58, 0xc9, 0x42, 0xd0, - 0x90, 0xad, 0xe9, 0x54, 0x50, 0x4c, 0x00, 0x57, - 0x56, 0x84, 0x68, 0xca, 0x24, 0xfe, 0x00, 0x39, - 0x58, 0x11, 0xb6, 0x42, 0xcd, 0x79, 0xda, 0x8e, - 0x9f, 0x8c, 0x60, 0xa4, 0xc0, 0xf9, 0x51, 0x3e, - 0x3a, 0xaa, 0x10, 0x17, 0x33, 0xe8, 0x32, 0x4b, - 0xe4, 0x26, 0xc8, 0x22, 0x7b, 0xb5, 0xe5, 0x97, - 0x82, 0xbb, 0x44, 0xee, 0xb4, 0xfa, 0x66, 0xd8, - 0xd9, 0x06, 0x63, 0x97, 0x97, 0xd5, 0x21, 0x07, - 0x27, 0x1b, 0x9c, 0x53, 0x81, 0xe1, 0x65, 0x71, - 0xec, 0x7c, 0x01, 0x51, 0xf5, 0xcd, 0x70, 0xa6, - 0xa3, 0x84, 0x4f, 0x12, 0x33, 0xfe, 0xe2, 0x4c, - 0x64, 0xc9, 0xd8, 0x07, 0x7e, 0x15, 0xe8, 0xe8, - 0xf1, 0x41, 0x28, 0xb4, 0x03, 0x5a, 0xeb, 0x2d, - 0x1a, 0xe6, 0x9b, 0x33, 0xe2, 0x12, 0x0c, 0x58, - 0xd1, 0xb3, 0xbd, 0x26, 0xc9, 0xed, 0x1a, 0xbb, - 0xbd, 0x7e, 0x27, 0x43, 0xfc, 0xff, 0x00, 0xe2, + 0x4d, 0xa2, 0x75, 0x84, 0x97, 0x31, 0x0b, 0x48, + 0x68, 0x8e, 0x58, 0x03, 0x40, 0xa1, 0x72, 0x8a, + 0x00, 0x08, 0x3d, 0x86, 0x52, 0xe1, 0x0f, 0x19, + 0x1f, 0x47, 0x1a, 0x01, 0x34, 0xb2, 0x38, 0x89, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x99, 0x8d, 0x68, 0x58, 0x75, 0x96, 0x92, 0x46, + 0x1f, 0xc5, 0x2b, 0xbb, 0x6a, 0x31, 0x07, 0x5d, + 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, 0x27, 0x06, + 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, 0x6f, 0x74, + 0xa3, 0x45, 0x18, 0x65, 0x26, 0x2b, 0x63, 0x1f, + 0xe6, 0x28, 0x37, 0x1c, 0x58, 0xc9, 0x42, 0xd0, + 0x90, 0xad, 0xe9, 0x54, 0x50, 0x4c, 0x00, 0x57, + 0x56, 0x84, 0x68, 0xca, 0x24, 0xfe, 0x00, 0x39, + 0x58, 0x11, 0xb6, 0x42, 0xcd, 0x79, 0xda, 0x8e, + 0x9f, 0x8c, 0x60, 0xa4, 0xc0, 0xf9, 0x51, 0x3e, + 0x3a, 0xaa, 0x10, 0x17, 0x33, 0xe8, 0x32, 0x4b, + 0xe4, 0x26, 0xc8, 0x22, 0x7b, 0xb5, 0xe5, 0x97, + 0x82, 0xbb, 0x44, 0xee, 0xb4, 0xfa, 0x66, 0xd8, + 0xd9, 0x06, 0x63, 0x97, 0x97, 0xd5, 0x21, 0x07, + 0x27, 0x1b, 0x9c, 0x53, 0x81, 0xe1, 0x65, 0x71, + 0xec, 0x7c, 0x01, 0x51, 0xf5, 0xcd, 0x70, 0xa6, + 0xa3, 0x84, 0x4f, 0x12, 0x33, 0xfe, 0xe2, 0x4c, + 0x64, 0xc9, 0xd8, 0x07, 0x7e, 0x15, 0xe8, 0xe8, + 0xf1, 0x41, 0x28, 0xb4, 0x03, 0x5a, 0xeb, 0x2d, + 0x1a, 0xe6, 0x9b, 0x33, 0xe2, 0x12, 0x0c, 0x58, + 0xd1, 0xb3, 0xbd, 0x26, 0xc9, 0xed, 0x1a, 0xbb, + 0xbd, 0x7e, 0x27, 0x43, 0xfc, 0xff, 0x00, 0xe2, }; static const uint8_t forceunlock602[] = { - 0x6c, 0x03, 0xf2, 0x1f, 0xe7, 0x37, 0x4b, 0x3a, - 0xc5, 0x12, 0x0e, 0x8a, 0x97, 0x64, 0x69, 0x2c, - 0xc4, 0xe7, 0x37, 0x73, 0xaf, 0xaf, 0x07, 0x8e, - 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, - 0x17, 0x20, 0xff, 0xb5, 0x08, 0x96, 0x54, 0xa1, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0xb7, 0x5e, 0xe9, 0xbf, 0xe5, 0xff, 0xe9, 0x35, - 0x22, 0x79, 0xe7, 0x0f, 0x4f, 0xa6, 0x4e, 0xf2, - 0x34, 0x26, 0x6d, 0xd9, 0xbe, 0xc0, 0x7f, 0xd5, - 0x8e, 0x7f, 0x30, 0x03, 0x57, 0x74, 0xda, 0xf5, - 0xf2, 0x9f, 0x32, 0x24, 0x48, 0xeb, 0xa8, 0x34, - 0xf9, 0xba, 0x68, 0xc9, 0x17, 0x18, 0x7d, 0x5e, - 0x88, 0x56, 0xa6, 0xce, 0x4f, 0x37, 0x0e, 0x29, - 0x59, 0x8d, 0xf9, 0xc8, 0x1c, 0xa8, 0x00, 0xd4, - 0x12, 0x62, 0xc2, 0x68, 0x4b, 0x1f, 0xdf, 0x08, - 0x67, 0x40, 0x8e, 0x35, 0x88, 0xfa, 0xda, 0x5c, - 0x42, 0x1c, 0x45, 0x1e, 0xa5, 0x79, 0x75, 0x94, - 0x01, 0xaf, 0x06, 0x5f, 0x89, 0x0f, 0xfa, 0x9b, - 0xcd, 0x60, 0x7d, 0x1d, 0x26, 0x4d, 0xd5, 0xd4, - 0xfa, 0xf2, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0xd7, 0x1d, 0xfe, 0xff, 0x00, 0x94, + 0x6c, 0x03, 0xf2, 0x1f, 0xe7, 0x37, 0x4b, 0x3a, + 0xc5, 0x12, 0x0e, 0x8a, 0x97, 0x64, 0x69, 0x2c, + 0xc4, 0xe7, 0x37, 0x73, 0xaf, 0xaf, 0x07, 0x8e, + 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, + 0x17, 0x20, 0xff, 0xb5, 0x08, 0x96, 0x54, 0xa1, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0xb7, 0x5e, 0xe9, 0xbf, 0xe5, 0xff, 0xe9, 0x35, + 0x22, 0x79, 0xe7, 0x0f, 0x4f, 0xa6, 0x4e, 0xf2, + 0x34, 0x26, 0x6d, 0xd9, 0xbe, 0xc0, 0x7f, 0xd5, + 0x8e, 0x7f, 0x30, 0x03, 0x57, 0x74, 0xda, 0xf5, + 0xf2, 0x9f, 0x32, 0x24, 0x48, 0xeb, 0xa8, 0x34, + 0xf9, 0xba, 0x68, 0xc9, 0x17, 0x18, 0x7d, 0x5e, + 0x88, 0x56, 0xa6, 0xce, 0x4f, 0x37, 0x0e, 0x29, + 0x59, 0x8d, 0xf9, 0xc8, 0x1c, 0xa8, 0x00, 0xd4, + 0x12, 0x62, 0xc2, 0x68, 0x4b, 0x1f, 0xdf, 0x08, + 0x67, 0x40, 0x8e, 0x35, 0x88, 0xfa, 0xda, 0x5c, + 0x42, 0x1c, 0x45, 0x1e, 0xa5, 0x79, 0x75, 0x94, + 0x01, 0xaf, 0x06, 0x5f, 0x89, 0x0f, 0xfa, 0x9b, + 0xcd, 0x60, 0x7d, 0x1d, 0x26, 0x4d, 0xd5, 0xd4, + 0xfa, 0xf2, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0xd7, 0x1d, 0xfe, 0xff, 0x00, 0x94, }; static const uint8_t forceunlock604[] = { - 0x67, 0xc3, 0x40, 0x93, 0xec, 0x8a, 0x9f, 0x9c, - 0xd6, 0x52, 0x68, 0xaa, 0x91, 0x65, 0x03, 0x41, - 0x8d, 0x2b, 0x96, 0x7e, 0xfa, 0xeb, 0x6e, 0x1f, - 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0xd2, 0x0b, 0x46, 0xe1, 0xc1, 0x27, 0x4a, 0x2b, - 0x1c, 0xb2, 0x0c, 0xf3, 0xaa, 0x23, 0x7c, 0x09, - 0xe7, 0x9c, 0xe7, 0xbd, 0xe7, 0xf3, 0xd8, 0xfe, - 0x44, 0x96, 0x15, 0xe9, 0x42, 0xf4, 0xc5, 0x7b, - 0xb6, 0x3d, 0xb7, 0x98, 0xcc, 0x5c, 0xb3, 0x71, - 0x52, 0x4e, 0x81, 0xb0, 0x0a, 0x0c, 0xb8, 0x9d, - 0x65, 0xb3, 0xa4, 0xd3, 0xd6, 0x09, 0xba, 0x57, - 0x50, 0x23, 0x3d, 0x3b, 0xe3, 0x80, 0x00, 0x41, - 0x3c, 0x67, 0x7a, 0xac, 0x44, 0x77, 0xaa, 0x93, - 0xad, 0x13, 0x99, 0x8d, 0x68, 0x58, 0x75, 0x96, - 0x92, 0x46, 0x1f, 0xc5, 0x2b, 0xbb, 0x6a, 0x31, - 0x07, 0x5d, 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, - 0x27, 0x06, 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, - 0x6f, 0x74, 0xa3, 0x45, 0x18, 0x65, 0x26, 0x2b, - 0x63, 0x1f, 0xe6, 0x28, 0x37, 0x1c, 0x58, 0xc9, - 0x42, 0xd0, 0x90, 0xad, 0xe9, 0x54, 0x50, 0x4c, - 0x00, 0x57, 0x56, 0x84, 0x68, 0xca, 0x24, 0xfe, - 0x58, 0x11, 0xb6, 0x42, 0xcd, 0x79, 0xda, 0x8e, - 0x9f, 0x8c, 0x60, 0xa4, 0xc0, 0xf9, 0x51, 0x3e, - 0x3a, 0xaa, 0x10, 0x17, 0x33, 0xe8, 0x32, 0x4b, - 0xe4, 0x26, 0xc8, 0x22, 0x7b, 0xb5, 0xe5, 0x97, - 0x82, 0xbb, 0xd7, 0x6a, 0xfc, 0xff, 0x00, 0x11, + 0x67, 0xc3, 0x40, 0x93, 0xec, 0x8a, 0x9f, 0x9c, + 0xd6, 0x52, 0x68, 0xaa, 0x91, 0x65, 0x03, 0x41, + 0x8d, 0x2b, 0x96, 0x7e, 0xfa, 0xeb, 0x6e, 0x1f, + 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0xd2, 0x0b, 0x46, 0xe1, 0xc1, 0x27, 0x4a, 0x2b, + 0x1c, 0xb2, 0x0c, 0xf3, 0xaa, 0x23, 0x7c, 0x09, + 0xe7, 0x9c, 0xe7, 0xbd, 0xe7, 0xf3, 0xd8, 0xfe, + 0x44, 0x96, 0x15, 0xe9, 0x42, 0xf4, 0xc5, 0x7b, + 0xb6, 0x3d, 0xb7, 0x98, 0xcc, 0x5c, 0xb3, 0x71, + 0x52, 0x4e, 0x81, 0xb0, 0x0a, 0x0c, 0xb8, 0x9d, + 0x65, 0xb3, 0xa4, 0xd3, 0xd6, 0x09, 0xba, 0x57, + 0x50, 0x23, 0x3d, 0x3b, 0xe3, 0x80, 0x00, 0x41, + 0x3c, 0x67, 0x7a, 0xac, 0x44, 0x77, 0xaa, 0x93, + 0xad, 0x13, 0x99, 0x8d, 0x68, 0x58, 0x75, 0x96, + 0x92, 0x46, 0x1f, 0xc5, 0x2b, 0xbb, 0x6a, 0x31, + 0x07, 0x5d, 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, + 0x27, 0x06, 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, + 0x6f, 0x74, 0xa3, 0x45, 0x18, 0x65, 0x26, 0x2b, + 0x63, 0x1f, 0xe6, 0x28, 0x37, 0x1c, 0x58, 0xc9, + 0x42, 0xd0, 0x90, 0xad, 0xe9, 0x54, 0x50, 0x4c, + 0x00, 0x57, 0x56, 0x84, 0x68, 0xca, 0x24, 0xfe, + 0x58, 0x11, 0xb6, 0x42, 0xcd, 0x79, 0xda, 0x8e, + 0x9f, 0x8c, 0x60, 0xa4, 0xc0, 0xf9, 0x51, 0x3e, + 0x3a, 0xaa, 0x10, 0x17, 0x33, 0xe8, 0x32, 0x4b, + 0xe4, 0x26, 0xc8, 0x22, 0x7b, 0xb5, 0xe5, 0x97, + 0x82, 0xbb, 0xd7, 0x6a, 0xfc, 0xff, 0x00, 0x11, }; static const uint8_t forceunlock606[] = { - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x37, 0x3f, 0xc9, 0x9f, 0x54, 0xd7, 0x20, 0x05, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0xb2, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x83, 0x8e, 0xfe, 0xff, 0x00, 0xac, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x37, 0x3f, 0xc9, 0x9f, 0x54, 0xd7, 0x20, 0x05, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0xb2, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x83, 0x8e, 0xfe, 0xff, 0x00, 0xac, }; static const uint8_t forceunlock610[] = { - 0xa4, 0xdb, 0xe6, 0x0e, 0x1a, 0xc1, 0x36, 0x88, - 0x53, 0xb8, 0xfb, 0x3c, 0xf0, 0x62, 0xea, 0x03, - 0x5e, 0xc6, 0x19, 0x85, 0x71, 0x20, 0x46, 0x11, - 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x99, 0x8d, 0x68, 0x58, 0x75, 0x96, 0x92, 0x46, - 0x1f, 0xc5, 0x2b, 0xbb, 0x6a, 0x31, 0x07, 0x5d, - 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, 0x27, 0x06, - 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, 0x6f, 0x74, - 0xa3, 0x45, 0x18, 0x65, 0x26, 0x2b, 0x63, 0x1f, - 0xe6, 0x28, 0x37, 0x1c, 0x58, 0xc9, 0x42, 0xd0, - 0x90, 0xad, 0xe9, 0x54, 0x50, 0x4c, 0x00, 0xf2, - 0x00, 0x57, 0x56, 0x84, 0x68, 0xca, 0x24, 0xfe, - 0x58, 0x11, 0xb6, 0x42, 0xcd, 0x79, 0xda, 0x8e, - 0x9f, 0x8c, 0x60, 0xa4, 0xc0, 0xf9, 0x51, 0x3e, - 0x3a, 0xaa, 0x10, 0x17, 0x33, 0xe8, 0x32, 0x4b, - 0xe4, 0x26, 0xc8, 0x22, 0x7b, 0xb5, 0xe5, 0x97, - 0x82, 0xbb, 0x44, 0xee, 0xb4, 0xfa, 0x66, 0xd8, - 0xd9, 0x06, 0x63, 0x97, 0x97, 0xd5, 0x21, 0x07, - 0x27, 0x1b, 0x9c, 0x53, 0x81, 0xe1, 0x65, 0x71, - 0xec, 0x7c, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x99, 0x8d, 0x68, 0x58, 0x75, 0x96, - 0x92, 0x46, 0x1f, 0xc5, 0x2b, 0xbb, 0x6a, 0x31, - 0x07, 0x5d, 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, - 0x27, 0x06, 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, - 0x6f, 0x74, 0xfb, 0xd8, 0xfc, 0xff, 0x00, 0x78, + 0xa4, 0xdb, 0xe6, 0x0e, 0x1a, 0xc1, 0x36, 0x88, + 0x53, 0xb8, 0xfb, 0x3c, 0xf0, 0x62, 0xea, 0x03, + 0x5e, 0xc6, 0x19, 0x85, 0x71, 0x20, 0x46, 0x11, + 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x99, 0x8d, 0x68, 0x58, 0x75, 0x96, 0x92, 0x46, + 0x1f, 0xc5, 0x2b, 0xbb, 0x6a, 0x31, 0x07, 0x5d, + 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, 0x27, 0x06, + 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, 0x6f, 0x74, + 0xa3, 0x45, 0x18, 0x65, 0x26, 0x2b, 0x63, 0x1f, + 0xe6, 0x28, 0x37, 0x1c, 0x58, 0xc9, 0x42, 0xd0, + 0x90, 0xad, 0xe9, 0x54, 0x50, 0x4c, 0x00, 0xf2, + 0x00, 0x57, 0x56, 0x84, 0x68, 0xca, 0x24, 0xfe, + 0x58, 0x11, 0xb6, 0x42, 0xcd, 0x79, 0xda, 0x8e, + 0x9f, 0x8c, 0x60, 0xa4, 0xc0, 0xf9, 0x51, 0x3e, + 0x3a, 0xaa, 0x10, 0x17, 0x33, 0xe8, 0x32, 0x4b, + 0xe4, 0x26, 0xc8, 0x22, 0x7b, 0xb5, 0xe5, 0x97, + 0x82, 0xbb, 0x44, 0xee, 0xb4, 0xfa, 0x66, 0xd8, + 0xd9, 0x06, 0x63, 0x97, 0x97, 0xd5, 0x21, 0x07, + 0x27, 0x1b, 0x9c, 0x53, 0x81, 0xe1, 0x65, 0x71, + 0xec, 0x7c, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x99, 0x8d, 0x68, 0x58, 0x75, 0x96, + 0x92, 0x46, 0x1f, 0xc5, 0x2b, 0xbb, 0x6a, 0x31, + 0x07, 0x5d, 0x2c, 0x8c, 0xb6, 0x6c, 0x5e, 0xbb, + 0x27, 0x06, 0x57, 0xa1, 0x20, 0x14, 0x78, 0x8b, + 0x6f, 0x74, 0xfb, 0xd8, 0xfc, 0xff, 0x00, 0x78, }; static const uint8_t forceunlock612[] = { - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0xbe, 0x32, 0x61, 0xa8, 0x96, 0xa8, 0xfa, 0xc0, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, - 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0xef, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, - 0xff, 0x90, 0x9b, 0x8e, 0xfe, 0xff, 0x00, 0x94, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0xbe, 0x32, 0x61, 0xa8, 0x96, 0xa8, 0xfa, 0xc0, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x4d, 0x83, 0x76, 0x8c, 0xcb, 0x01, 0xd0, 0x98, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0xff, 0x90, + 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, 0x00, 0xef, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x03, 0xdc, 0xcd, 0x7d, 0xd3, 0x83, + 0xff, 0x90, 0x9b, 0x8e, 0xfe, 0xff, 0x00, 0x94, }; +// clang-format on + +const uint8_t *getOrigPatch(uint8_t *build_date) +{ + if (memcmp(build_date, date500, 5) == 0) + return orig_patch500; + else if (memcmp(build_date, date502, 5) == 0) + return orig_patch502; + else if (memcmp(build_date, date504, 5) == 0) + return orig_patch504; + else if (memcmp(build_date, date506, 5) == 0) + return orig_patch506; + else if (memcmp(build_date, date506mx, 5) == 0) + return orig_patch506mx; + else if (memcmp(build_date, date510, 5) == 0) + return orig_patch510; + else if (memcmp(build_date, date512, 5) == 0) + return orig_patch512; + else if (memcmp(build_date, date514, 5) == 0) + return orig_patch514; + else if (memcmp(build_date, date600, 5) == 0) + return orig_patch600; + else if (memcmp(build_date, date602, 5) == 0) + return orig_patch602_B; /* orig_patch602_A check manually */ + else if (memcmp(build_date, date604, 5) == 0) + return orig_patch604; + else if (memcmp(build_date, date606, 5) == 0) + return orig_patch606; + else if (memcmp(build_date, date610, 5) == 0) + return orig_patch610_B; /* orig_patch610_A check manually */ + else if (memcmp(build_date, date612, 5) == 0) + return orig_patch612; + + return 0; +} + +const uint8_t *getPatch(uint8_t *build_date) +{ + if (memcmp(build_date, date500, 5) == 0) + return patch500; + else if (memcmp(build_date, date502, 5) == 0) + return patch502; + else if (memcmp(build_date, date504, 5) == 0) + return patch504; + else if (memcmp(build_date, date506, 5) == 0) + return patch506; + else if (memcmp(build_date, date506mx, 5) == 0) + return patch506mx; + else if (memcmp(build_date, date510, 5) == 0) + return patch510; + else if (memcmp(build_date, date512, 5) == 0) + return patch512; + else if (memcmp(build_date, date514, 5) == 0) + return patch514; + else if (memcmp(build_date, date600, 5) == 0) + return patch600; + else if (memcmp(build_date, date602, 5) == 0) + return patch602; + else if (memcmp(build_date, date604, 5) == 0) + return patch604; + else if (memcmp(build_date, date606, 5) == 0) + return patch606; + else if (memcmp(build_date, date610, 5) == 0) + return patch610; + else if (memcmp(build_date, date612, 5) == 0) + return patch612; + + return 0; +} + const uint8_t *getForceUnlock(uint8_t *build_date) { - if (memcmp(build_date, date500, 5) == 0) - return forceunlock500; - else if (memcmp(build_date, date502, 5) == 0) - return forceunlock502; - else if (memcmp(build_date, date504, 5) == 0) - return forceunlock504; - else if (memcmp(build_date, date506, 5) == 0) - return forceunlock506; - else if (memcmp(build_date, date506mx, 5) == 0) - return forceunlock506mx; - /*else if (memcmp(build_date, date510, 5) == 0) - return forceunlock510;*/ - else if (memcmp(build_date, date512, 5) == 0) - return forceunlock512; - /*else if (memcmp(build_date, date514, 5) == 0) - return forceunlock514;*/ - else if (memcmp(build_date, date600, 5) == 0) - return forceunlock600; - else if (memcmp(build_date, date602, 5) == 0) - return forceunlock602; - else if (memcmp(build_date, date604, 5) == 0) - return forceunlock604; - else if (memcmp(build_date, date606, 5) == 0) - return forceunlock606; - else if (memcmp(build_date, date610, 5) == 0) - return forceunlock610; - else if (memcmp(build_date, date612, 5) == 0) - return forceunlock612; + if (memcmp(build_date, date500, 5) == 0) + return forceunlock500; + else if (memcmp(build_date, date502, 5) == 0) + return forceunlock502; + else if (memcmp(build_date, date504, 5) == 0) + return forceunlock504; + else if (memcmp(build_date, date506, 5) == 0) + return forceunlock506; + else if (memcmp(build_date, date506mx, 5) == 0) + return forceunlock506mx; + /* else if (memcmp(build_date, date510, 5) == 0) + return forceunlock510; */ + else if (memcmp(build_date, date512, 5) == 0) + return forceunlock512; + /* else if (memcmp(build_date, date514, 5) == 0) + return forceunlock514; */ + else if (memcmp(build_date, date600, 5) == 0) + return forceunlock600; + else if (memcmp(build_date, date602, 5) == 0) + return forceunlock602; + else if (memcmp(build_date, date604, 5) == 0) + return forceunlock604; + else if (memcmp(build_date, date606, 5) == 0) + return forceunlock606; + else if (memcmp(build_date, date610, 5) == 0) + return forceunlock610; + else if (memcmp(build_date, date612, 5) == 0) + return forceunlock612; - return 0; + return 0; } char installPatch(const uint8_t *patch) { - if (!OpenConfig(1, 0, 7)) - return 0; - uint8_t cfg[0x70]; - for (int i = 0; i < 7; i++) - if (!ReadConfig(&cfg[0x10 * i])) - return 0; - if (!CloseConfig()) - return 0; + if (!OpenConfig(1, 0, 7)) + return 0; + uint8_t cfg[0x70]; + for (int i = 0; i < 7; i++) + if (!ReadConfig(&cfg[0x10 * i])) + return 0; + if (!CloseConfig()) + return 0; - if (!OpenConfig(1, 1, 7 + 14)) - return 0; - for (int i = 0; i < 7; i++) - if (!WriteConfig(&cfg[0x10 * i])) - return 0; - for (int i = 0; i < 14; i++) - if (!WriteConfig(&patch[0x10 * i])) - { - // if we fail here, let's try to fix the config. - if (!CloseConfig()) - return 0; - - if (!OpenConfig(1, 1, 7)) - return 0; - for (int i = 0; i < 7; i++) - if (!WriteConfig(&cfg[0x10 * i])) - return 0; - if (!CloseConfig()) - return 0; - - return 0; - } - if (!CloseConfig()) - return 0; - - if (!OpenConfig(1, 1, 7)) - return 0; - for (int i = 0; i < 7; i++) - if (!WriteConfig(&cfg[0x10 * i])) - return 0; - if (!CloseConfig()) - return 0; - - return 1; -} + if (!OpenConfig(1, 1, 7 + 14)) + return 0; + for (int i = 0; i < 7; i++) + if (!WriteConfig(&cfg[0x10 * i])) + return 0; + for (int i = 0; i < 14; i++) + if (!WriteConfig(&patch[0x10 * i])) + { + // if we fail here, let's try to fix the config. + if (!CloseConfig()) + return 0; + if (!OpenConfig(1, 1, 7)) + return 0; + + for (int j = 0; j < 7; j++) + if (!WriteConfig(&cfg[0x10 * j])) + return 0; + if (!CloseConfig()) + return 0; + return 0; + } + if (!CloseConfig()) + return 0; + if (!OpenConfig(1, 1, 7)) + return 0; + for (int i = 0; i < 7; i++) + if (!WriteConfig(&cfg[0x10 * i])) + return 0; + if (!CloseConfig()) + return 0; + + return 1; +} diff --git a/exploit.h b/exploit.h index d6fe5bd..be99da3 100644 --- a/exploit.h +++ b/exploit.h @@ -14,6 +14,529 @@ * along with this program. If not, see . */ +const uint8_t *getOrigPatch(uint8_t *build_date); const uint8_t *getPatch(uint8_t *build_date); const uint8_t *getForceUnlock(uint8_t *build_date); char installPatch(const uint8_t *patch); + +// clang-format off + +/* static const uint8_t zeropatch[] = { + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; */ +// zeropatch +static const uint8_t orig_patch500[] = { + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +// zeropatch +static const uint8_t orig_patch502[] = { + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +static const uint8_t orig_patch504[] = { + 0xB1, 0xEA, 0x8B, 0xC0, 0xC8, 0x19, 0x84, 0x35, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xA6, 0x84, 0x83, 0x24, 0xDD, 0xF6, 0x9A, 0xEB, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x61, 0x7D, 0x23, 0xA3, 0x51, 0x05, 0x4E, 0x8C, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x2E, 0xA7, 0xEA, 0x33, 0x14, 0xAD, 0x99, 0xD4, + 0x5D, 0xA6, 0x0D, 0xCC, 0xD7, 0x1B, 0x3D, 0x78, + 0xCB, 0x27, 0x51, 0xB4, 0x85, 0x40, 0xF0, 0x96, + 0xB6, 0xDA, 0xEF, 0x69, 0x9D, 0x96, 0x4B, 0x9C, + 0x95, 0x6D, 0x23, 0xA4, 0xE1, 0x23, 0x57, 0x1C, + 0xCE, 0x8E, 0xD3, 0x2F, 0x1C, 0xC6, 0x55, 0x4B, + 0xCD, 0xFB, 0x5A, 0xEF, 0xD3, 0x9B, 0x3A, 0xD8, + 0xB4, 0x89, 0x9C, 0xB7, 0x72, 0x97, 0x00, 0x27, + 0xBA, 0xDF, 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, + 0xE6, 0xE8, 0x74, 0xDF, 0x39, 0xD0, 0xD5, 0x17, + 0x88, 0xCC, 0xB0, 0x1B, 0x75, 0x1B, 0x05, 0xA5, + 0xD6, 0x21, 0xB0, 0x70, 0xD9, 0xA5, 0x76, 0x8B, + 0x24, 0xB6, 0x09, 0x0C, 0x65, 0x47, 0xF1, 0x05, + 0x7C, 0xD2, 0xB1, 0x82, 0x87, 0xFF, 0x3D, 0xA3, + 0xFC, 0xED, 0x98, 0x4B, 0x96, 0x4F, 0xF8, 0x3F, + 0x32, 0x7C, 0xFA, 0x38, 0x6B, 0x13, 0xC7, 0x69, + 0x9A, 0x24, 0xB3, 0x75, 0x64, 0xC2, 0x39, 0x65, + 0x2D, 0x43, 0x2C, 0x30, 0x15, 0x3D, 0x01, 0xB2, + 0x7D, 0x34, 0x64, 0x66, 0x1F, 0x67, 0x50, 0x20, + 0xC8, 0xB4, 0x13, 0xBD, 0xC9, 0x30, 0x98, 0xFE, + 0xE2, 0xE7, 0x23, 0x07, 0x3E, 0x3A, 0x51, 0xD2, + 0xFF, 0x90, 0xB7, 0x7A, 0xFD, 0xFF, 0x00, 0xE3, +}; +// zeropatch +static const uint8_t orig_patch506[] = { + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +// zeropatch +static const uint8_t orig_patch506mx[] = { + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +static const uint8_t orig_patch510[] = { + 0x1A, 0xCE, 0xDA, 0xEB, 0x39, 0x3B, 0xC5, 0x27, + 0x4D, 0x90, 0xE2, 0x7F, 0x40, 0xC8, 0xF2, 0x44, + 0x77, 0x1C, 0x9B, 0x3A, 0x47, 0x27, 0xE7, 0xC9, + 0x64, 0x4B, 0x04, 0xB7, 0x5C, 0x85, 0xEA, 0x8D, + 0x17, 0x65, 0x31, 0x14, 0x0F, 0xD2, 0xB7, 0x7E, + 0x4C, 0x24, 0xCC, 0x76, 0x22, 0x74, 0xA9, 0x87, + 0x2D, 0x64, 0xD6, 0x51, 0x71, 0xF3, 0xE7, 0xA5, + 0xB5, 0x41, 0x50, 0xCC, 0x5C, 0xB4, 0xD7, 0xD1, + 0xC9, 0x9B, 0x8B, 0x09, 0xC7, 0x46, 0x92, 0x15, + 0x9E, 0x18, 0xB1, 0x6E, 0xC1, 0xA3, 0x68, 0xD8, + 0x63, 0xC2, 0x1D, 0x5A, 0xD2, 0xDB, 0xB8, 0x00, + 0xC1, 0x60, 0x7C, 0x7B, 0x93, 0x91, 0x2B, 0xAD, + 0x9F, 0x75, 0x1C, 0xA0, 0xDC, 0x16, 0x61, 0xED, + 0xD3, 0xDC, 0x8E, 0x9B, 0x51, 0x81, 0x00, 0x79, + 0xEB, 0x88, 0x53, 0xAE, 0x0D, 0xCC, 0xA7, 0xE2, + 0x10, 0xE3, 0x93, 0x42, 0x97, 0x09, 0x59, 0x1C, + 0xF7, 0x4F, 0x5A, 0x63, 0x3D, 0x8F, 0xA7, 0x39, + 0x78, 0x05, 0xF5, 0x47, 0x0F, 0x99, 0xB0, 0x67, + 0x03, 0x5D, 0x97, 0x7E, 0x14, 0x09, 0x26, 0x26, + 0xBD, 0x3D, 0x9E, 0x18, 0xB1, 0x6E, 0xC1, 0xA3, + 0x68, 0xD8, 0x9B, 0x4E, 0x49, 0x76, 0xD8, 0xA7, + 0xAC, 0x1C, 0xC0, 0xC3, 0xC5, 0x61, 0x77, 0xD6, + 0xB1, 0xAF, 0x70, 0x8C, 0x57, 0xC2, 0xD9, 0x6A, + 0x57, 0xAB, 0xC2, 0x39, 0xDD, 0x61, 0xC8, 0x36, + 0xE6, 0x67, 0x9E, 0x18, 0xB1, 0x6E, 0xC1, 0xA3, + 0x68, 0xD8, 0x29, 0xE5, 0xB8, 0xE5, 0xBD, 0xDE, + 0x78, 0x26, 0xE9, 0x5A, 0xAC, 0xDB, 0x07, 0xF9, + 0x21, 0x59, 0xD3, 0x94, 0xFB, 0xFF, 0x00, 0xAF, +}; +static const uint8_t orig_patch512[] = { + 0x93, 0x85, 0x9A, 0xF5, 0x2B, 0x5B, 0xD1, 0xBD, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x49, 0x9A, 0xE4, 0xAA, 0xE1, 0x5E, 0x67, 0x75, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xDE, 0xA6, 0x9B, 0xE9, 0xD1, 0xD8, 0x45, 0x61, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xE1, 0xFD, 0x79, 0xCB, 0x33, 0xB3, 0x1C, 0x78, + 0x53, 0xFD, 0x10, 0x86, 0x6C, 0x11, 0x4A, 0x3E, + 0xA3, 0xDE, 0x31, 0xBF, 0xD9, 0x23, 0xC1, 0x3D, + 0x8C, 0x5D, 0x05, 0x0D, 0xBF, 0x98, 0x8F, 0x51, + 0x24, 0x0E, 0xB8, 0x08, 0xB5, 0x3C, 0x6A, 0x46, + 0xF0, 0xA7, 0x2E, 0xCF, 0x42, 0xAB, 0x24, 0x25, + 0x09, 0xB4, 0x0E, 0x80, 0xF1, 0xAD, 0xBE, 0x68, + 0x42, 0x80, 0xBE, 0x7E, 0x6A, 0x27, 0x00, 0x18, + 0xFC, 0xF3, 0x2C, 0x8C, 0xB6, 0x6C, 0x5E, 0xBB, + 0x27, 0x06, 0x57, 0xA1, 0x20, 0x14, 0x78, 0x8B, + 0x6F, 0x74, 0xA3, 0x45, 0x18, 0x65, 0x26, 0x2B, + 0x63, 0x1F, 0xE6, 0x28, 0x37, 0x1C, 0x58, 0xC9, + 0x42, 0xD0, 0x90, 0xAD, 0xE9, 0x54, 0x50, 0x4C, + 0x00, 0x57, 0x56, 0x84, 0x68, 0xCA, 0x24, 0xFE, + 0x58, 0x11, 0xB6, 0x42, 0xCD, 0x79, 0xDA, 0x8E, + 0x9F, 0x8C, 0x60, 0xA4, 0xC0, 0xF9, 0x51, 0x3E, + 0x3A, 0xAA, 0x10, 0x17, 0x33, 0xE8, 0x32, 0x4B, + 0xE4, 0x26, 0xC8, 0x22, 0x7B, 0xB5, 0xE5, 0x97, + 0x82, 0xBB, 0x44, 0xEE, 0xB4, 0xFA, 0x66, 0xD8, + 0xD9, 0x06, 0x63, 0x97, 0x97, 0xD5, 0x21, 0x07, + 0x27, 0x1B, 0x9C, 0x53, 0x81, 0xE1, 0x65, 0x71, + 0xEC, 0x7C, 0x63, 0x66, 0xFE, 0xFF, 0x00, 0x4F, +}; +// zeropatch +static const uint8_t orig_patch514[] = { + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +static const uint8_t orig_patch600[] = { + 0x4D, 0xA2, 0x75, 0x84, 0x97, 0x31, 0x0B, 0x48, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x00, 0x08, 0x3D, 0x86, 0x52, 0xE1, 0x0F, 0x19, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x99, 0x8D, 0x68, 0x58, 0x75, 0x96, 0x92, 0x46, + 0x1F, 0xC5, 0x2B, 0xBB, 0x6A, 0x31, 0x07, 0x5D, + 0x2C, 0x8C, 0xB6, 0x6C, 0x5E, 0xBB, 0x27, 0x06, + 0x57, 0xA1, 0x20, 0x14, 0x78, 0x8B, 0x6F, 0x74, + 0xA3, 0x45, 0x18, 0x65, 0x26, 0x2B, 0x63, 0x1F, + 0xE6, 0x28, 0x37, 0x1C, 0x58, 0xC9, 0x42, 0xD0, + 0x90, 0xAD, 0xE9, 0x54, 0x50, 0x4C, 0x00, 0x57, + 0x56, 0x84, 0x68, 0xCA, 0x24, 0xFE, 0x00, 0x73, + 0x58, 0x11, 0xB6, 0x42, 0xCD, 0x79, 0xDA, 0x8E, + 0x9F, 0x8C, 0x60, 0xA4, 0xC0, 0xF9, 0x51, 0x3E, + 0x3A, 0xAA, 0x10, 0x17, 0x33, 0xE8, 0x32, 0x4B, + 0xE4, 0x26, 0xC8, 0x22, 0x7B, 0xB5, 0xE5, 0x97, + 0x82, 0xBB, 0x44, 0xEE, 0xB4, 0xFA, 0x66, 0xD8, + 0xD9, 0x06, 0x63, 0x97, 0x97, 0xD5, 0x21, 0x07, + 0x27, 0x1B, 0x9C, 0x53, 0x81, 0xE1, 0x65, 0x71, + 0xEC, 0x7C, 0x01, 0x51, 0xF5, 0xCD, 0x70, 0xA6, + 0xA3, 0x84, 0x4F, 0x12, 0x33, 0xFE, 0xE2, 0x4C, + 0x64, 0xC9, 0xD8, 0x07, 0x7E, 0x15, 0xE8, 0xE8, + 0xF1, 0x41, 0x28, 0xB4, 0x03, 0x5A, 0xEB, 0x2D, + 0x1A, 0xE6, 0x9B, 0x33, 0xE2, 0x12, 0x0C, 0x58, + 0xD1, 0xB3, 0xBD, 0x26, 0xC9, 0xED, 0x1A, 0xBB, + 0xBD, 0x7E, 0x87, 0xA9, 0xFD, 0xFF, 0x00, 0x1B, +}; +static const uint8_t orig_patch602_A[] = { + 0x00, 0xC6, 0x58, 0xEE, 0x14, 0x41, 0x00, 0x09, + 0xD4, 0x65, 0xD7, 0x17, 0x3F, 0x36, 0x9F, 0x1A, + 0x27, 0x3C, 0x9C, 0xDD, 0xBA, 0xFB, 0x9C, 0x4C, + 0xD4, 0xDA, 0xBC, 0x52, 0xC2, 0xB0, 0x80, 0xB7, + 0x46, 0x5C, 0x65, 0xAA, 0x3F, 0x93, 0xBA, 0x4D, + 0x17, 0x20, 0xFF, 0xB5, 0x08, 0x96, 0x54, 0xA1, + 0xCF, 0x5B, 0x38, 0x97, 0x73, 0x72, 0x1F, 0x94, + 0x31, 0x1C, 0xD8, 0x03, 0xF1, 0xB2, 0xA5, 0x0C, + 0x86, 0xF9, 0x88, 0xA2, 0x82, 0x71, 0xD0, 0xA8, + 0x1B, 0x55, 0x10, 0xFA, 0x6C, 0xC5, 0x43, 0x2F, + 0x2D, 0xE6, 0x1F, 0x48, 0xC4, 0x2F, 0x60, 0x2B, + 0x65, 0x9F, 0x05, 0x50, 0xD1, 0x41, 0x34, 0x36, + 0x17, 0xB6, 0x15, 0x77, 0xBE, 0x1E, 0x8F, 0x8C, + 0x40, 0x9E, 0x4B, 0x66, 0x28, 0x64, 0x00, 0xE4, + 0x55, 0x97, 0xA2, 0xFE, 0xC8, 0x5C, 0xEA, 0x6F, + 0x74, 0xF2, 0xE7, 0x78, 0x98, 0xEE, 0x3B, 0xF1, + 0x35, 0x1A, 0x9B, 0xE0, 0x3A, 0xBB, 0x1B, 0x03, + 0xDA, 0xC4, 0xF8, 0xB4, 0x6B, 0x92, 0x2A, 0xBD, + 0x8C, 0x84, 0x86, 0xAB, 0x3A, 0xE0, 0x95, 0x60, + 0x1A, 0x54, 0xF8, 0xB4, 0x6B, 0x92, 0x2A, 0xBD, + 0x8C, 0x84, 0x8F, 0xA8, 0x42, 0x47, 0x6B, 0x31, + 0x65, 0x6C, 0xD9, 0x48, 0xA9, 0x6B, 0x32, 0xE3, + 0x98, 0xD8, 0x6E, 0x8C, 0x7E, 0xC5, 0xEC, 0x41, + 0xBE, 0x6A, 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, + 0xFF, 0x90, 0x99, 0x8D, 0x68, 0x58, 0x75, 0x96, + 0x92, 0x46, 0x1F, 0xC5, 0x2B, 0xBB, 0x6A, 0x31, + 0x07, 0x5D, 0x2C, 0x8C, 0xB6, 0x6C, 0x5E, 0xBB, + 0x27, 0x06, 0x63, 0x7C, 0xFE, 0xFF, 0x00, 0x01, +}; +static const uint8_t orig_patch602_B[] = { + 0xDB, 0xC8, 0x71, 0x2D, 0xA6, 0x01, 0x85, 0x03, + 0x0F, 0xBD, 0x85, 0x53, 0x5F, 0x34, 0xE7, 0x99, + 0xF0, 0xA5, 0x3B, 0xCE, 0xA7, 0x38, 0xA7, 0x4E, + 0xF1, 0xB1, 0x46, 0x0D, 0x7B, 0xC1, 0xA3, 0xFE, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x51, 0x72, 0x45, 0xC3, 0xBD, 0x7B, 0x89, 0xEF, + 0x61, 0xE9, 0xD1, 0xB0, 0x81, 0x48, 0xF5, 0xEC, + 0xEC, 0x4A, 0x95, 0x55, 0x80, 0xC4, 0xAC, 0x4E, + 0x61, 0xE9, 0xD1, 0xB0, 0x81, 0x48, 0xF5, 0xEC, + 0xA8, 0xD3, 0xE2, 0xB6, 0x62, 0xDA, 0x9C, 0x9F, + 0x61, 0xE9, 0xD1, 0xB0, 0x81, 0x48, 0xF5, 0xEC, + 0xD5, 0xE6, 0x2B, 0x93, 0x91, 0x5B, 0x98, 0xCB, + 0xAB, 0xE4, 0x8A, 0xE3, 0xF0, 0xCD, 0x00, 0x35, + 0x12, 0x90, 0xBC, 0xE5, 0xF2, 0x77, 0x19, 0xE3, + 0x8F, 0x17, 0x55, 0xD7, 0xDB, 0x89, 0xA1, 0xCD, + 0x9A, 0xC7, 0x30, 0x50, 0x8A, 0x96, 0x5C, 0x3C, + 0x40, 0x8C, 0x9E, 0xFA, 0xAB, 0x87, 0x02, 0xF6, + 0xFE, 0x12, 0xB4, 0x98, 0xD3, 0xC6, 0x60, 0x9E, + 0x21, 0x69, 0x5C, 0xCF, 0xCC, 0xFD, 0x1E, 0x00, + 0xB2, 0x36, 0x4E, 0x57, 0x32, 0x2A, 0x4C, 0x69, + 0xD4, 0x8A, 0x64, 0xA7, 0x34, 0xA3, 0xAB, 0x46, + 0x04, 0x26, 0x55, 0xD7, 0xDB, 0x89, 0xA1, 0xCD, + 0x9A, 0xC7, 0x51, 0x69, 0xFB, 0xEE, 0x98, 0xFC, + 0x5A, 0x25, 0x44, 0x05, 0xE5, 0x9A, 0x8A, 0x84, + 0x80, 0x30, 0xB6, 0x48, 0xD8, 0x48, 0xE9, 0x43, + 0x59, 0xAD, 0x41, 0xD8, 0xE8, 0xD9, 0x1F, 0x4E, + 0x1C, 0x10, 0x8F, 0x17, 0xF6, 0xFF, 0x00, 0x0B, +}; +static const uint8_t orig_patch604[] = { + 0x67, 0xC3, 0x40, 0x93, 0xEC, 0x8A, 0x9F, 0x9C, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x8D, 0x2B, 0x96, 0x7E, 0xFA, 0xEB, 0x6E, 0x1F, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xD2, 0x0B, 0x46, 0xE1, 0xC1, 0x27, 0x4A, 0x2B, + 0x1C, 0xB2, 0x0C, 0xF3, 0xAA, 0x23, 0x7C, 0x09, + 0xE7, 0x9C, 0xE7, 0xBD, 0xE7, 0xF3, 0xD8, 0xFE, + 0x44, 0x96, 0x15, 0xE9, 0x42, 0xF4, 0xC5, 0x7B, + 0xB6, 0x3D, 0xB7, 0x98, 0xCC, 0x5C, 0xB3, 0x71, + 0x52, 0x4E, 0x81, 0xB0, 0x0A, 0x0C, 0xB8, 0x9D, + 0x65, 0xB3, 0xA4, 0xD3, 0xD6, 0x09, 0xBA, 0x57, + 0x50, 0x23, 0x3D, 0x3B, 0xE3, 0x80, 0x00, 0x9F, + 0x3C, 0x67, 0x7A, 0xAC, 0x44, 0x77, 0xAA, 0x93, + 0xAD, 0x13, 0x99, 0x8D, 0x68, 0x58, 0x75, 0x96, + 0x92, 0x46, 0x1F, 0xC5, 0x2B, 0xBB, 0x6A, 0x31, + 0x07, 0x5D, 0x2C, 0x8C, 0xB6, 0x6C, 0x5E, 0xBB, + 0x27, 0x06, 0x57, 0xA1, 0x20, 0x14, 0x78, 0x8B, + 0x6F, 0x74, 0xA3, 0x45, 0x18, 0x65, 0x26, 0x2B, + 0x63, 0x1F, 0xE6, 0x28, 0x37, 0x1C, 0x58, 0xC9, + 0x42, 0xD0, 0x90, 0xAD, 0xE9, 0x54, 0x50, 0x4C, + 0x00, 0x57, 0x56, 0x84, 0x68, 0xCA, 0x24, 0xFE, + 0x58, 0x11, 0xB6, 0x42, 0xCD, 0x79, 0xDA, 0x8E, + 0x9F, 0x8C, 0x60, 0xA4, 0xC0, 0xF9, 0x51, 0x3E, + 0x3A, 0xAA, 0x10, 0x17, 0x33, 0xE8, 0x32, 0x4B, + 0xE4, 0x26, 0xC8, 0x22, 0x7B, 0xB5, 0xE5, 0x97, + 0x82, 0xBB, 0xCB, 0xD9, 0xFD, 0xFF, 0x00, 0xAD, +}; +// zeropatch +static const uint8_t orig_patch606[] = { + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +static const uint8_t orig_patch610_A[] = { + 0x7E, 0xAC, 0x5F, 0xB3, 0x78, 0x19, 0xA2, 0x10, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x29, 0x4B, 0x22, 0x84, 0x54, 0xA2, 0x4A, 0xA1, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x86, 0x86, 0xC8, 0xF4, 0xB1, 0x68, 0xAD, 0x10, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x3B, 0x48, 0xFC, 0x39, 0x80, 0x9A, 0x94, 0x3C, + 0xF8, 0xB1, 0x05, 0x23, 0x77, 0x1F, 0x37, 0xFB, + 0x97, 0x8B, 0x22, 0xFC, 0xF7, 0xF1, 0x7D, 0x62, + 0x09, 0x21, 0x3F, 0xF9, 0x43, 0xFD, 0xE1, 0x81, + 0x47, 0x2D, 0xCF, 0xF8, 0x24, 0x52, 0x31, 0xE6, + 0xA3, 0x45, 0x18, 0x65, 0x26, 0x2B, 0x63, 0x1F, + 0xE6, 0x28, 0x37, 0x1C, 0x58, 0xC9, 0x42, 0xD0, + 0x90, 0xAD, 0xE9, 0x54, 0x50, 0x4C, 0x00, 0xCD, + 0x00, 0x57, 0x56, 0x84, 0x68, 0xCA, 0x24, 0xFE, + 0x58, 0x11, 0xB6, 0x42, 0xCD, 0x79, 0xDA, 0x8E, + 0x9F, 0x8C, 0x60, 0xA4, 0xC0, 0xF9, 0x51, 0x3E, + 0x3A, 0xAA, 0x10, 0x17, 0x33, 0xE8, 0x32, 0x4B, + 0xE4, 0x26, 0xC8, 0x22, 0x7B, 0xB5, 0xE5, 0x97, + 0x82, 0xBB, 0x44, 0xEE, 0xB4, 0xFA, 0x66, 0xD8, + 0xD9, 0x06, 0x63, 0x97, 0x97, 0xD5, 0x21, 0x07, + 0x27, 0x1B, 0x9C, 0x53, 0x81, 0xE1, 0x65, 0x71, + 0xEC, 0x7C, 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, + 0xFF, 0x90, 0x99, 0x8D, 0x68, 0x58, 0x75, 0x96, + 0x92, 0x46, 0x1F, 0xC5, 0x2B, 0xBB, 0x6A, 0x31, + 0x07, 0x5D, 0x2C, 0x8C, 0xB6, 0x6C, 0x5E, 0xBB, + 0x27, 0x06, 0x57, 0xA1, 0x20, 0x14, 0x78, 0x8B, + 0x6F, 0x74, 0x7F, 0xEE, 0xFD, 0xFF, 0x00, 0xDD, +}; +static const uint8_t orig_patch610_B[] = { + 0xA4, 0xDB, 0xE6, 0x0E, 0x1A, 0xC1, 0x36, 0x88, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x5E, 0xC6, 0x19, 0x85, 0x71, 0x20, 0x46, 0x11, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x99, 0x8D, 0x68, 0x58, 0x75, 0x96, 0x92, 0x46, + 0x1F, 0xC5, 0x2B, 0xBB, 0x6A, 0x31, 0x07, 0x5D, + 0x2C, 0x8C, 0xB6, 0x6C, 0x5E, 0xBB, 0x27, 0x06, + 0x57, 0xA1, 0x20, 0x14, 0x78, 0x8B, 0x6F, 0x74, + 0xA3, 0x45, 0x18, 0x65, 0x26, 0x2B, 0x63, 0x1F, + 0xE6, 0x28, 0x37, 0x1C, 0x58, 0xC9, 0x42, 0xD0, + 0x90, 0xAD, 0xE9, 0x54, 0x50, 0x4C, 0x00, 0x5D, + 0x00, 0x57, 0x56, 0x84, 0x68, 0xCA, 0x24, 0xFE, + 0x58, 0x11, 0xB6, 0x42, 0xCD, 0x79, 0xDA, 0x8E, + 0x9F, 0x8C, 0x60, 0xA4, 0xC0, 0xF9, 0x51, 0x3E, + 0x3A, 0xAA, 0x10, 0x17, 0x33, 0xE8, 0x32, 0x4B, + 0xE4, 0x26, 0xC8, 0x22, 0x7B, 0xB5, 0xE5, 0x97, + 0x82, 0xBB, 0x44, 0xEE, 0xB4, 0xFA, 0x66, 0xD8, + 0xD9, 0x06, 0x63, 0x97, 0x97, 0xD5, 0x21, 0x07, + 0x27, 0x1B, 0x9C, 0x53, 0x81, 0xE1, 0x65, 0x71, + 0xEC, 0x7C, 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, + 0xFF, 0x90, 0x99, 0x8D, 0x68, 0x58, 0x75, 0x96, + 0x92, 0x46, 0x1F, 0xC5, 0x2B, 0xBB, 0x6A, 0x31, + 0x07, 0x5D, 0x2C, 0x8C, 0xB6, 0x6C, 0x5E, 0xBB, + 0x27, 0x06, 0x57, 0xA1, 0x20, 0x14, 0x78, 0x8B, + 0x6F, 0x74, 0x3F, 0x4B, 0xFE, 0xFF, 0x00, 0xBF, +}; +// zeropatch +static const uint8_t orig_patch612[] = { + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0x03, 0xDC, 0xCD, 0x7D, 0xD3, 0x83, 0xFF, 0x90, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +// clang-format on diff --git a/irx/compiled/placeholder b/irx/compiled/placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/irx/source/Rules.bin.make b/irx/source/Rules.bin.make index f87ec8b..596ec24 100644 --- a/irx/source/Rules.bin.make +++ b/irx/source/Rules.bin.make @@ -1,17 +1,17 @@ -# _____ ___ ____ ___ ____ -# ____| | ____| | | |____| -# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. -#----------------------------------------------------------------------- -# Copyright 2001-2004, ps2dev - http://www.ps2dev.org -# Licenced under Academic Free License version 2.0 -# Review ps2sdk README & LICENSE files for further details. - -IOP_BIN_DIR ?= irx/ - -IOP_BIN ?= $(shell basename $(CURDIR)).irx -IOP_BIN := $(IOP_BIN:%=$(IOP_BIN_DIR)%) - -all:: $(IOP_BIN) - -clean:: - rm -f -r $(IOP_OBJS_DIR) $(IOP_BIN_DIR) +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. + +IOP_BIN_DIR ?= irx/ + +IOP_BIN ?= $(shell basename $(CURDIR)).irx +IOP_BIN := $(IOP_BIN:%=$(IOP_BIN_DIR)%) + +all:: $(IOP_BIN) + +clean:: + rm -f -r $(IOP_OBJS_DIR) $(IOP_BIN_DIR) diff --git a/irx/source/Rules.make b/irx/source/Rules.make deleted file mode 100644 index d652534..0000000 --- a/irx/source/Rules.make +++ /dev/null @@ -1,99 +0,0 @@ -# _____ ___ ____ ___ ____ -# ____| | ____| | | |____| -# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. -#----------------------------------------------------------------------- -# Copyright 2001-2004, ps2dev - http://www.ps2dev.org -# Licenced under Academic Free License version 2.0 -# Review ps2sdk README & LICENSE files for further details. - -IOP_CC_VERSION := $(shell $(IOP_CC) --version 2>&1 | sed -n 's/^.*(GCC) //p') - -IOP_OBJS_DIR ?= obj/ -IOP_SRC_DIR ?= src/ -IOP_INC_DIR ?= include/ - -ifeq ($(IOP_CC_VERSION),3.2.2) -ASFLAGS_TARGET = -march=r3000 -endif - -ifeq ($(IOP_CC_VERSION),3.2.3) -ASFLAGS_TARGET = -march=r3000 -endif - -# include dir -IOP_INCS := $(IOP_INCS) -I$(IOP_SRC_DIR) -I$(IOP_SRC_DIR)include -I$(IOP_INC_DIR) -I$(PS2SDK)/iop/include -I$(PS2SDK)/common/include - -# C compiler flags -# -fno-builtin is required to prevent the GCC built-in functions from being included, -# for finer-grained control over what goes into each IRX. -IOP_CFLAGS := -D_IOP -fno-builtin -O2 -G0 -Wall $(IOP_INCS) $(IOP_CFLAGS) -# Linker flags -IOP_LDFLAGS := -nostdlib -s $(IOP_LDFLAGS) - -# Additional C compiler flags for GCC >=v5.3.0 -# -msoft-float is to "remind" GCC/Binutils that the soft-float ABI is to be used. This is due to a bug, which -# results in the ABI not being passed correctly to binutils and iop-as defaults to the hard-float ABI instead. -# -mno-explicit-relocs is required to work around the fact that GCC is now known to -# output multiple LO relocs after one HI reloc (which the IOP kernel cannot deal with). -# -fno-toplevel-reorder (for IOP import and export tables only) disables toplevel reordering by GCC v4.2 and later. -# Without it, the import and export tables can be broken apart by GCC's optimizations. -ifneq ($(IOP_CC_VERSION),3.2.2) -ifneq ($(IOP_CC_VERSION),3.2.3) -IOP_CFLAGS += -msoft-float -mno-explicit-relocs -IOP_IETABLE_CFLAGS := -fno-toplevel-reorder -endif -endif - -# Assembler flags -IOP_ASFLAGS := $(ASFLAGS_TARGET) -EL -G0 $(IOP_ASFLAGS) - -IOP_OBJS := $(IOP_OBJS:%=$(IOP_OBJS_DIR)%) - -# Externally defined variables: IOP_BIN, IOP_OBJS, IOP_LIB - -# These macros can be used to simplify certain build rules. -IOP_C_COMPILE = $(IOP_CC) $(IOP_CFLAGS) - -$(IOP_OBJS_DIR)%.o: $(IOP_SRC_DIR)%.c - $(IOP_C_COMPILE) -c $< -o $@ - -$(IOP_OBJS_DIR)%.o: $(IOP_SRC_DIR)%.S - $(IOP_C_COMPILE) -c $< -o $@ - -$(IOP_OBJS_DIR)%.o: $(IOP_SRC_DIR)%.s - $(IOP_AS) $(IOP_ASFLAGS) $< -o $@ - -.INTERMEDIATE: $(IOP_OBJS_DIR)build-imports.c $(IOP_OBJS_DIR)build-exports.c - -# Rules to build imports.lst. -$(IOP_OBJS_DIR)build-imports.c: $(IOP_SRC_DIR)imports.lst - $(ECHO) "#include \"irx_imports.h\"" > $@ - cat $< >> $@ - -$(IOP_OBJS_DIR)imports.o: $(IOP_OBJS_DIR)build-imports.c - $(IOP_C_COMPILE) $(IOP_IETABLE_CFLAGS) -c $< -o $@ - -# Rules to build exports.tab. -$(IOP_OBJS_DIR)build-exports.c: $(IOP_SRC_DIR)exports.tab - $(ECHO) "#include \"irx.h\"" > $@ - cat $< >> $@ - -$(IOP_OBJS_DIR)exports.o: $(IOP_OBJS_DIR)build-exports.c - $(IOP_C_COMPILE) $(IOP_IETABLE_CFLAGS) -c $< -o $@ - -$(IOP_OBJS_DIR): - $(MKDIR) -p $(IOP_OBJS_DIR) - -$(IOP_BIN_DIR): - $(MKDIR) -p $(IOP_BIN_DIR) - -$(IOP_LIB_DIR): - $(MKDIR) -p $(IOP_LIB_DIR) - -$(IOP_OBJS): | $(IOP_OBJS_DIR) - -$(IOP_BIN): $(IOP_OBJS) | $(IOP_BIN_DIR) - $(IOP_C_COMPILE) -o $(IOP_BIN) $(IOP_OBJS) $(IOP_LDFLAGS) $(IOP_LIBS) - -$(IOP_LIB): $(IOP_OBJS) | $(IOP_LIB_DIR) - $(IOP_AR) cru $(IOP_LIB) $(IOP_OBJS) diff --git a/irx/source/masswatcher/Makefile b/irx/source/masswatcher/Makefile index cef85f0..9be6b4d 100644 --- a/irx/source/masswatcher/Makefile +++ b/irx/source/masswatcher/Makefile @@ -1,14 +1,19 @@ -# _____ ___ ____ ___ ____ -# ____| | ____| | | |____| -# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. -#----------------------------------------------------------------------- -# Copyright 2001-2004, ps2dev - http://www.ps2dev.org -# Licenced under Academic Free License version 2.0 -# Review ps2sdk README & LICENSE files for further details. -# -IOP_BIN = masswatcher.irx -IOP_OBJS = masswatcher.o imports.o exports.o - -include $(PS2SDK)/Defs.make -include ../Rules.bin.make -include ../Rules.make +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +# +IOP_BIN = masswatcher.irx +IOP_OBJS = masswatcher.o imports.o exports.o + +IOP_SRC_DIR = src/ +IOP_OPTFLAGS = -O2 +IOP_INCS += -I$(IOP_SRC_DIR) + +include $(PS2SDK)/Defs.make +include ../Rules.bin.make +include $(PS2SDK)/samples/Makefile.pref +include $(PS2SDK)/samples/Makefile.iopglobal diff --git a/irx/source/masswatcher/include/masswatcher.h b/irx/source/masswatcher/include/masswatcher.h index d2d7c84..01c9c0f 100644 --- a/irx/source/masswatcher/include/masswatcher.h +++ b/irx/source/masswatcher/include/masswatcher.h @@ -1,17 +1,17 @@ -/* - * Copyright (c) 2021 MechaResearch - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#define MASSWATCHER_HEADER 0x80000F01 +/* + * Copyright (c) 2021 MechaResearch + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#define MASSWATCHER_HEADER 0x80000F01 diff --git a/irx/source/masswatcher/src/exports.tab b/irx/source/masswatcher/src/exports.tab index 0b1465b..78f488b 100644 --- a/irx/source/masswatcher/src/exports.tab +++ b/irx/source/masswatcher/src/exports.tab @@ -1,8 +1,8 @@ -void _funcret(){}; - -DECLARE_EXPORT_TABLE(masswatcher, 1, 1) - DECLARE_EXPORT(_start) - DECLARE_EXPORT(_funcret) - DECLARE_EXPORT(_funcret) - DECLARE_EXPORT(_funcret) -END_EXPORT_TABLE +void _funcret(){}; + +DECLARE_EXPORT_TABLE(masswatcher, 1, 1) + DECLARE_EXPORT(_start) + DECLARE_EXPORT(_funcret) + DECLARE_EXPORT(_funcret) + DECLARE_EXPORT(_funcret) +END_EXPORT_TABLE diff --git a/irx/source/masswatcher/src/imports.lst b/irx/source/masswatcher/src/imports.lst index 58be239..4c6844e 100644 --- a/irx/source/masswatcher/src/imports.lst +++ b/irx/source/masswatcher/src/imports.lst @@ -1,29 +1,29 @@ -usbmass_IMPORTS_start -I_UsbMassRegisterCallback -usbmass_IMPORTS_end - -loadcore_IMPORTS_start -I_RegisterLibraryEntries -loadcore_IMPORTS_end - -sifcmd_IMPORTS_start -I_sceSifInitRpc -I_sceSifSetRpcQueue -I_sceSifRegisterRpc -I_sceSifRpcLoop -sifcmd_IMPORTS_end - -sifman_IMPORTS_start -I_sceSifCheckInit -I_sceSifInit -sifman_IMPORTS_end - -stdio_IMPORTS_start -I_printf -stdio_IMPORTS_end - -thbase_IMPORTS_start -I_CreateThread -I_StartThread -I_GetThreadId -thbase_IMPORTS_end +usbmass_IMPORTS_start +I_UsbMassRegisterCallback +usbmass_IMPORTS_end + +loadcore_IMPORTS_start +I_RegisterLibraryEntries +loadcore_IMPORTS_end + +sifcmd_IMPORTS_start +I_sceSifInitRpc +I_sceSifSetRpcQueue +I_sceSifRegisterRpc +I_sceSifRpcLoop +sifcmd_IMPORTS_end + +sifman_IMPORTS_start +I_sceSifCheckInit +I_sceSifInit +sifman_IMPORTS_end + +stdio_IMPORTS_start +I_printf +stdio_IMPORTS_end + +thbase_IMPORTS_start +I_CreateThread +I_StartThread +I_GetThreadId +thbase_IMPORTS_end diff --git a/irx/source/masswatcher/src/masswatcher.c b/irx/source/masswatcher/src/masswatcher.c index 5e6f9c5..21ca1fb 100644 --- a/irx/source/masswatcher/src/masswatcher.c +++ b/irx/source/masswatcher/src/masswatcher.c @@ -1,91 +1,92 @@ -/* - * Copyright (c) 2021 MechaResearch - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#include "irx_imports.h" -#include "masswatcher.h" - -#define MODNAME "masswatcher" -IRX_ID(MODNAME, 1, 2); - -extern struct irx_export_table _exp_masswatcher; - -static SifRpcDataQueue_t SifMassQD; -static SifRpcServerData_t SifMassData; -static int SifMassThreadID; - -static unsigned char SifServerBuffer[0x1000]; - -static char massState[2] = { 0, 0 }; - -static void *MassHeader(int function, void *buffer, int nbytes) -{ - char *params = (char *) buffer; - - *params = massState[0] || massState[1]; - - return buffer; -} - -static void SifMassThread(void *parameters) -{ - if(!sceSifCheckInit()){ - printf("yet sif hasn't been init\n"); - sceSifInit(); - } - - sceSifInitRpc(0); - sceSifSetRpcQueue(&SifMassQD, GetThreadId()); - sceSifRegisterRpc(&SifMassData, MASSWATCHER_HEADER, &MassHeader, SifServerBuffer, NULL, NULL, &SifMassQD); - sceSifRpcLoop(&SifMassQD); -} - -static void usbmass_cb0(int cause) -{ - if (cause == USBMASS_DEV_EV_CONN) - massState[0] = 1; - else if (cause == USBMASS_DEV_EV_DISCONN) - massState[0] = 0; -} - -static void usbmass_cb1(int cause) -{ - if (cause == USBMASS_DEV_EV_CONN) - massState[1] = 1; - else if (cause == USBMASS_DEV_EV_DISCONN) - massState[1] = 0; -} - -int _start(int argc, char *argv[]) -{ - if(RegisterLibraryEntries(&_exp_masswatcher) != 0) - return MODULE_NO_RESIDENT_END; - - UsbMassRegisterCallback(0, usbmass_cb0); - UsbMassRegisterCallback(1, usbmass_cb1); - - iop_thread_t thread; - thread.attr = TH_C; - thread.priority = 0x28; - thread.stacksize = 0x800; - - thread.thread=&SifMassThread; - SifMassThreadID = CreateThread(&thread); - if(SifMassThreadID == 0) - return MODULE_NO_RESIDENT_END; - StartThread(SifMassThreadID, NULL); - - return MODULE_RESIDENT_END; -} +/* + * Copyright (c) 2021 MechaResearch + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#include "irx_imports.h" +#include "masswatcher.h" + +#define MODNAME "masswatcher" +IRX_ID(MODNAME, 1, 2); + +extern struct irx_export_table _exp_masswatcher; + +static SifRpcDataQueue_t SifMassQD; +static SifRpcServerData_t SifMassData; +static int SifMassThreadID; + +static unsigned char SifServerBuffer[0x1000]; + +static char massState[2] = {0, 0}; + +static void *MassHeader(int function, void *buffer, int nbytes) +{ + char *params = (char *)buffer; + + *params = massState[0] || massState[1]; + + return buffer; +} + +static void SifMassThread(void *parameters) +{ + if (!sceSifCheckInit()) + { + printf("yet sif hasn't been init\n"); + sceSifInit(); + } + + sceSifInitRpc(0); + sceSifSetRpcQueue(&SifMassQD, GetThreadId()); + sceSifRegisterRpc(&SifMassData, MASSWATCHER_HEADER, &MassHeader, SifServerBuffer, NULL, NULL, &SifMassQD); + sceSifRpcLoop(&SifMassQD); +} + +static void usbmass_cb0(int cause) +{ + if (cause == USBMASS_DEV_EV_CONN) + massState[0] = 1; + else if (cause == USBMASS_DEV_EV_DISCONN) + massState[0] = 0; +} + +static void usbmass_cb1(int cause) +{ + if (cause == USBMASS_DEV_EV_CONN) + massState[1] = 1; + else if (cause == USBMASS_DEV_EV_DISCONN) + massState[1] = 0; +} + +int _start(int argc, char *argv[]) +{ + if (RegisterLibraryEntries(&_exp_masswatcher) != 0) + return MODULE_NO_RESIDENT_END; + + UsbMassRegisterCallback(0, usbmass_cb0); + UsbMassRegisterCallback(1, usbmass_cb1); + + iop_thread_t thread; + thread.attr = TH_C; + thread.priority = 0x28; + thread.stacksize = 0x800; + + thread.thread = &SifMassThread; + SifMassThreadID = CreateThread(&thread); + if (SifMassThreadID == 0) + return MODULE_NO_RESIDENT_END; + StartThread(SifMassThreadID, NULL); + + return MODULE_RESIDENT_END; +} diff --git a/irx/source/mechaproxy/Makefile b/irx/source/mechaproxy/Makefile index 86f54ed..9ed3bec 100644 --- a/irx/source/mechaproxy/Makefile +++ b/irx/source/mechaproxy/Makefile @@ -1,14 +1,19 @@ -# _____ ___ ____ ___ ____ -# ____| | ____| | | |____| -# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. -#----------------------------------------------------------------------- -# Copyright 2001-2004, ps2dev - http://www.ps2dev.org -# Licenced under Academic Free License version 2.0 -# Review ps2sdk README & LICENSE files for further details. -# -IOP_BIN = mechaproxy.irx -IOP_OBJS = mechaproxy.o imports.o exports.o - -include $(PS2SDK)/Defs.make -include ../Rules.bin.make -include ../Rules.make +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +# +IOP_BIN = mechaproxy.irx +IOP_OBJS = mechaproxy.o imports.o exports.o + +IOP_SRC_DIR = src/ +IOP_OPTFLAGS = -O2 +IOP_INCS += -I$(IOP_SRC_DIR) + +include $(PS2SDK)/Defs.make +include ../Rules.bin.make +include $(PS2SDK)/samples/Makefile.pref +include $(PS2SDK)/samples/Makefile.iopglobal diff --git a/irx/source/mechaproxy/include/mechaproxy.h b/irx/source/mechaproxy/include/mechaproxy.h index 3afa603..1f41047 100644 --- a/irx/source/mechaproxy/include/mechaproxy.h +++ b/irx/source/mechaproxy/include/mechaproxy.h @@ -1,26 +1,26 @@ -/* - * Copyright (c) 2021 MechaResearch - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -struct MechaScmdParams -{ - u8 cmd; - u8 input[16]; - u8 inputlength; - u8 output[16]; - int result; -}; - -#define MECHAPROXY_SCMD_HEADER 0x80000A01 +/* + * Copyright (c) 2021 MechaResearch + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +struct MechaScmdParams +{ + u8 cmd; + u8 input[16]; + u8 inputlength; + u8 output[16]; + int result; +}; + +#define MECHAPROXY_SCMD_HEADER 0x80000A01 diff --git a/irx/source/mechaproxy/src/exports.tab b/irx/source/mechaproxy/src/exports.tab index 60829ec..f0087e8 100644 --- a/irx/source/mechaproxy/src/exports.tab +++ b/irx/source/mechaproxy/src/exports.tab @@ -1,8 +1,8 @@ -void _funcret(){}; - -DECLARE_EXPORT_TABLE(mechaproxy, 1, 1) - DECLARE_EXPORT(_start) - DECLARE_EXPORT(_funcret) - DECLARE_EXPORT(_funcret) - DECLARE_EXPORT(_funcret) -END_EXPORT_TABLE +void _funcret(){}; + +DECLARE_EXPORT_TABLE(mechaproxy, 1, 1) + DECLARE_EXPORT(_start) + DECLARE_EXPORT(_funcret) + DECLARE_EXPORT(_funcret) + DECLARE_EXPORT(_funcret) +END_EXPORT_TABLE diff --git a/irx/source/mechaproxy/src/imports.lst b/irx/source/mechaproxy/src/imports.lst index ce499aa..47453f2 100644 --- a/irx/source/mechaproxy/src/imports.lst +++ b/irx/source/mechaproxy/src/imports.lst @@ -1,29 +1,29 @@ -cdvdman_IMPORTS_start -I_sceCdApplySCmd -cdvdman_IMPORTS_end - -loadcore_IMPORTS_start -I_RegisterLibraryEntries -loadcore_IMPORTS_end - -sifcmd_IMPORTS_start -I_sceSifInitRpc -I_sceSifSetRpcQueue -I_sceSifRegisterRpc -I_sceSifRpcLoop -sifcmd_IMPORTS_end - -sifman_IMPORTS_start -I_sceSifCheckInit -I_sceSifInit -sifman_IMPORTS_end - -stdio_IMPORTS_start -I_printf -stdio_IMPORTS_end - -thbase_IMPORTS_start -I_CreateThread -I_StartThread -I_GetThreadId -thbase_IMPORTS_end +cdvdman_IMPORTS_start +I_sceCdApplySCmd +cdvdman_IMPORTS_end + +loadcore_IMPORTS_start +I_RegisterLibraryEntries +loadcore_IMPORTS_end + +sifcmd_IMPORTS_start +I_sceSifInitRpc +I_sceSifSetRpcQueue +I_sceSifRegisterRpc +I_sceSifRpcLoop +sifcmd_IMPORTS_end + +sifman_IMPORTS_start +I_sceSifCheckInit +I_sceSifInit +sifman_IMPORTS_end + +stdio_IMPORTS_start +I_printf +stdio_IMPORTS_end + +thbase_IMPORTS_start +I_CreateThread +I_StartThread +I_GetThreadId +thbase_IMPORTS_end diff --git a/irx/source/mechaproxy/src/irx_imports.h b/irx/source/mechaproxy/src/irx_imports.h index 2ea3e34..8dda2fa 100644 --- a/irx/source/mechaproxy/src/irx_imports.h +++ b/irx/source/mechaproxy/src/irx_imports.h @@ -1,14 +1,14 @@ -#ifndef IOP_IRX_IMPORTS_H -#define IOP_IRX_IMPORTS_H - -#include - -/* Please keep these in alphabetical order! */ -#include -#include -#include -#include -#include -#include - -#endif /* IOP_IRX_IMPORTS_H */ +#ifndef IOP_IRX_IMPORTS_H +#define IOP_IRX_IMPORTS_H + +#include + +/* Please keep these in alphabetical order! */ +#include +#include +#include +#include +#include +#include + +#endif /* IOP_IRX_IMPORTS_H */ diff --git a/irx/source/mechaproxy/src/mechaproxy.c b/irx/source/mechaproxy/src/mechaproxy.c index 879400f..5debe4e 100644 --- a/irx/source/mechaproxy/src/mechaproxy.c +++ b/irx/source/mechaproxy/src/mechaproxy.c @@ -1,70 +1,71 @@ -/* - * Copyright (c) 2021 MechaResearch - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#include "irx_imports.h" -#include "mechaproxy.h" - -#define MODNAME "mechaproxy" -IRX_ID(MODNAME, 1, 2); - -extern struct irx_export_table _exp_mechaproxy; - -static SifRpcDataQueue_t SifMechaScmdQD; -static SifRpcServerData_t SifMechaScmdData; -static int SifMechaScmdThreadID; - -static unsigned char SifServerBuffer[0x1000]; - -static void *MechaScmdHeader(int function, void *buffer, int nbytes) -{ - struct MechaScmdParams *params = (struct MechaScmdParams *) buffer; - - params->result = sceCdApplySCmd(params->cmd, params->input, params->inputlength, params->output); - - return buffer; -} - -static void SifMechaScmdThread(void *parameters) -{ - if(!sceSifCheckInit()){ - printf("yet sif hasn't been init\n"); - sceSifInit(); - } - - sceSifInitRpc(0); - sceSifSetRpcQueue(&SifMechaScmdQD, GetThreadId()); - sceSifRegisterRpc(&SifMechaScmdData, MECHAPROXY_SCMD_HEADER, &MechaScmdHeader, SifServerBuffer, NULL, NULL, &SifMechaScmdQD); - sceSifRpcLoop(&SifMechaScmdQD); -} - -int _start(int argc, char *argv[]) -{ - if(RegisterLibraryEntries(&_exp_mechaproxy) != 0) - return MODULE_NO_RESIDENT_END; - - iop_thread_t thread; - thread.attr = TH_C; - thread.priority = 0x28; - thread.stacksize = 0x800; - - thread.thread=&SifMechaScmdThread; - SifMechaScmdThreadID = CreateThread(&thread); - if(SifMechaScmdThreadID == 0) - return MODULE_NO_RESIDENT_END; - StartThread(SifMechaScmdThreadID, NULL); - - return MODULE_RESIDENT_END; -} +/* + * Copyright (c) 2021 MechaResearch + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#include "irx_imports.h" +#include "mechaproxy.h" + +#define MODNAME "mechaproxy" +IRX_ID(MODNAME, 1, 2); + +extern struct irx_export_table _exp_mechaproxy; + +static SifRpcDataQueue_t SifMechaScmdQD; +static SifRpcServerData_t SifMechaScmdData; +static int SifMechaScmdThreadID; + +static unsigned char SifServerBuffer[0x1000]; + +static void *MechaScmdHeader(int function, void *buffer, int nbytes) +{ + struct MechaScmdParams *params = (struct MechaScmdParams *)buffer; + + params->result = sceCdApplySCmd(params->cmd, params->input, params->inputlength, params->output); + + return buffer; +} + +static void SifMechaScmdThread(void *parameters) +{ + if (!sceSifCheckInit()) + { + printf("yet sif hasn't been init\n"); + sceSifInit(); + } + + sceSifInitRpc(0); + sceSifSetRpcQueue(&SifMechaScmdQD, GetThreadId()); + sceSifRegisterRpc(&SifMechaScmdData, MECHAPROXY_SCMD_HEADER, &MechaScmdHeader, SifServerBuffer, NULL, NULL, &SifMechaScmdQD); + sceSifRpcLoop(&SifMechaScmdQD); +} + +int _start(int argc, char *argv[]) +{ + if (RegisterLibraryEntries(&_exp_mechaproxy) != 0) + return MODULE_NO_RESIDENT_END; + + iop_thread_t thread; + thread.attr = TH_C; + thread.priority = 0x28; + thread.stacksize = 0x800; + + thread.thread = &SifMechaScmdThread; + SifMechaScmdThreadID = CreateThread(&thread); + if (SifMechaScmdThreadID == 0) + return MODULE_NO_RESIDENT_END; + StartThread(SifMechaScmdThreadID, NULL); + + return MODULE_RESIDENT_END; +} diff --git a/main.c b/main.c index f69ad4c..0cbab68 100644 --- a/main.c +++ b/main.c @@ -1,1101 +1,1580 @@ -/* - * Copyright (c) 2021 MechaResearch - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mecha.h" -#include "exploit.h" -#include "pad.h" -#include "binaries.h" -#include "ui.h" -#include "mass.h" - -static void ResetIOP() -{ - SifInitRpc(0); - SifIopReset("", 0); - while(!SifIopSync()); - SifInitRpc(0); - SifLoadFileInit(); -} - -char unlockNVM() -{ - gsKit_clear(gsGlobal, Black); - - uint8_t version[3]; - getMechaVersion(version); - - uint8_t build_date[5]; - getMechaBuildDate(build_date); - - struct GSTEXTURE_holder *versionTextures = ui_printf(10, 100, 42, 0xFFFFFF, "Mecha version: %d.%02d\n", version[1], version[2]); - struct GSTEXTURE_holder *buildTextures = ui_printf(10, 150, 42, 0xFFFFFF, "Mecha build date: 20%02x/%02x/%02x %02x:%02x\n", build_date[0], build_date[1], build_date[2], build_date[3], build_date[4]); - - const uint8_t *patch = getPatch(build_date); - - struct GSTEXTURE_holder *exploitTextures = draw_text(10, 200, 42, 0xFFFFFF, "Press O to install exploit.\n"); - struct GSTEXTURE_holder *exitTextures = draw_text(10, 250, 42, 0xFFFFFF, "Press X to exit.\n"); - - drawFrame(); - - while (1) - { - u32 new_pad = ReadCombinedPadStatus(); - - if(new_pad & PAD_CIRCLE) - { - break; - } - else if(new_pad & PAD_CROSS) - { - gsKit_clear(gsGlobal, Black); - ResetIOP(); - LoadExecPS2("rom0:OSDSYS", 0, NULL); - - return 0; - } - } - - if (!installPatch(patch)) - { - struct GSTEXTURE_holder *errorTextures = draw_text(10, 300, 42, 0xFFFFFF, "Failed to install the patch.\n"); - - drawFrame(); - - freeGSTEXTURE_holder(versionTextures); - freeGSTEXTURE_holder(buildTextures); - freeGSTEXTURE_holder(exploitTextures); - freeGSTEXTURE_holder(exitTextures); - freeGSTEXTURE_holder(errorTextures); - - return 0; - } - - freeGSTEXTURE_holder(versionTextures); - freeGSTEXTURE_holder(buildTextures); - freeGSTEXTURE_holder(exploitTextures); - freeGSTEXTURE_holder(exitTextures); - - return 1; -} - -struct MENU -{ - const char *title; - const char *x_text; - const char *o_text; - uint8_t option_count; - const char *options[10]; -}; - -int drawMenu(struct MENU *menu) -{ - int selected_menu = 0; - gsKit_clear(gsGlobal, Black); - - while(1) - { - u32 new_pad = ReadCombinedPadStatus(); - - if(new_pad & PAD_UP) - { - selected_menu--; - } - else if(new_pad & PAD_DOWN) - { - selected_menu++; - } - else if(new_pad & PAD_CIRCLE) - { - return -1; - } - else if(new_pad & PAD_CROSS) - { - return selected_menu; - } - - if (selected_menu < 0) - selected_menu = menu->option_count - 1; - else if (selected_menu > menu->option_count - 1) - selected_menu = 0; - - gsKit_clear(gsGlobal, Black); - - int title_x, title_y; - getTextSize(52, menu->title, &title_x, &title_y); - - struct GSTEXTURE_holder *TitleTexture = draw_text((gsGlobal->Width - title_x) / 2, 10, 52, 0xFFFFFF, menu->title); - struct GSTEXTURE_holder *oTexture = draw_text(10, -74, 42, 0xFFFFFF, menu->o_text); - struct GSTEXTURE_holder *xTexture = draw_text(-10, -74, 42, 0xFFFFFF, menu->x_text); - - struct GSTEXTURE_holder *menus[256]; - memset(menus, 0, sizeof(menus)); - - for (int i = 0; i < menu->option_count; i++) - { - int menu_x, menu_y; - getTextSize(42, menu->options[i], &menu_x, &menu_y); - - menus[i] = draw_text((gsGlobal->Width - menu_x) / 2, 100 + i * 50, 42, selected_menu == i ? 0xFF6040 : 0xFFFFFF, menu->options[i]); - } - - drawFrame(); - - for (int i = 0; i < 256; i++) - if (menus[i]) - freeGSTEXTURE_holder(menus[i]); - - freeGSTEXTURE_holder(xTexture); - freeGSTEXTURE_holder(oTexture); - freeGSTEXTURE_holder(TitleTexture); - } -} - -uint8_t region_keyseed[] = { 0x4d, 0x65, 0x63, 0x68, 0x61, 0x50, 0x77, 0x6e, 0x00, 0xec }; -uint8_t region_ciphertext_dex[] = { 0x1a, 0x74, 0xac, 0xb2, 0xb0, 0xae, 0x15, 0xdf, 0x00, 0xc1 }; - -// 0 - Japan -uint8_t region_params_japan[] = { 0x4a, 0x4a, 0x6a, 0x70, 0x6e, 0x4a, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uint8_t region_ciphertext_japan_cex[] = { 0xf1, 0xef, 0x50, 0xec, 0x1c, 0x2e, 0xc5, 0x69, 0x00, 0x6b }; - -// 1 - USA -uint8_t region_params_usa[] = { 0x41, 0x41, 0x65, 0x6e, 0x67, 0x41, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uint8_t region_ciphertext_usa_cex[] = { 0xb8, 0x42, 0xd5, 0xbc, 0x53, 0xa1, 0x96, 0xe6, 0x00, 0x04 }; - -// 2 - Oceania -uint8_t region_params_oceania[] = { 0x45, 0x45, 0x65, 0x6e, 0x67, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uint8_t region_ciphertext_oceania_cex[] = { 0x64, 0xaa, 0x23, 0x25, 0x28, 0x5c, 0x14, 0xf3, 0x00, 0x1e }; - -// 3 - UK -// same as europe - -// 4 - Europe -uint8_t region_params_europe[] = { 0x45, 0x45, 0x65, 0x6e, 0x67, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uint8_t region_ciphertext_europe_cex[] = { 0x54, 0x88, 0x4f, 0x90, 0x76, 0x4d, 0xcb, 0xeb, 0x00, 0xcb }; - -// 5 - Korea -uint8_t region_params_korea[] = { 0x48, 0x4b, 0x6b, 0x6f, 0x72, 0x4a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uint8_t region_ciphertext_korea_cex[] = { 0x2a, 0xf0, 0x38, 0x2d, 0xef, 0xe5, 0x48, 0xa4, 0x00, 0xc0 }; - -// 6 - Asia -uint8_t region_params_asia[] = { 0x48, 0x48, 0x65, 0x6e, 0x67, 0x4a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uint8_t region_ciphertext_asia_cex[] = { 0x2a, 0xf0, 0x38, 0x2d, 0xef, 0xe5, 0x48, 0xa4, 0x00, 0xc0 }; - -// 7 - Tawain -uint8_t region_params_tawain[] = { 0x48, 0x48, 0x74, 0x63, 0x68, 0x4a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00 }; -// region_ciphertext is same as asia - -// 8 - Russia -uint8_t region_params_russia[] = { 0x45, 0x52, 0x65, 0x6e, 0x67, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uint8_t region_ciphertext_russia_cex[] = { 0x3e, 0x11, 0xc1, 0xbb, 0xfb, 0x26, 0x2b, 0x4c, 0x00, 0x9c }; - -// 9 - China -uint8_t region_ciphertext_china_cex[] = { 0x0f, 0x5d, 0xb8, 0xa2, 0x9d, 0x85, 0xcc, 0x76, 0x00, 0xd5 }; - -// 10 - ??? - -// 11 - Mexico / ??? -uint8_t region_ciphertext_mexico_cex[] = { 0x35, 0x1a, 0x92, 0x9a, 0x05, 0x5b, 0xdc, 0x40, 0x00, 0x08 }; - -// 12 - ??? - -void sum_buffer(uint8_t *buffer, int length) -{ - uint8_t sum = 0; - for (int i = 0; i < length - 2; i++) - sum += buffer[i]; - buffer[length - 2] = 0; - buffer[length - 1] = ~sum; -} - -char write_region(uint8_t *region_params, uint8_t *model_number, uint8_t *region_ciphertext) -{ - if (region_params) - { - for (int i = 0; i < 12; i += 2) - if (!WriteNVM(192 + i / 2, *(uint16_t *) ®ion_params[i])) - break; - } - - if (model_number) - { - for (int i = 0; i < 18; i += 2) - if (!WriteNVM(216 + i / 2, *(uint16_t *) &model_number[i])) - break; - } - - if (region_ciphertext) - { - for (int i = 0; i < 10; i += 2) - if (!WriteNVM(227 + i / 2, *(uint16_t *) ®ion_keyseed[i])) - break; - - for (int i = 0; i < 10; i += 2) - if (!WriteNVM(232 + i / 2, *(uint16_t *) ®ion_ciphertext[i])) - break; - } - - return 1; -} - -void selectCexDex(char *isDex) -{ - gsKit_clear(gsGlobal, Black); - - struct MENU menu; - menu.title = "Select console type"; - menu.x_text = "X Select"; - menu.o_text = "O Exit"; - menu.option_count = 2; - menu.options[0] = "CEX (retail)"; - menu.options[1] = "Retail-DEX"; - int selected = drawMenu(&menu); - - gsKit_clear(gsGlobal, Black); - - drawFrame(); - - if (selected == -1) - { - ResetIOP(); - LoadExecPS2("rom0:OSDSYS", 0, NULL); - SleepThread(); - } - - *isDex = selected == 1; -} - - -void selectModel(char isDex, char *isSlim, char *model) -{ - if (isDex) - strcpy(model, "DTL-H"); - else - strcpy(model, "SCPH-"); - - gsKit_clear(gsGlobal, Black); - - struct MENU menu; - menu.title = "Select model"; - menu.x_text = "X Select"; - menu.o_text = "O Exit"; - menu.option_count = 7; - - for (int i = 0; i < menu.option_count; i++) - { - char *option = malloc(20); - strcpy(option, model); - menu.options[i] = option; - } - - strcat((char *) menu.options[0], "50xxx"); - strcat((char *) menu.options[1], "55xxx"); - strcat((char *) menu.options[2], "70xxx"); - strcat((char *) menu.options[3], "75xxx"); - strcat((char *) menu.options[4], "77xxx"); - strcat((char *) menu.options[5], "79xxx"); - strcat((char *) menu.options[6], "90xxx"); - - int selected = drawMenu(&menu); - - for (int i = 0; i < menu.option_count; i++) - free((char *) menu.options[i]); - - if (selected == -1) - { - ResetIOP(); - LoadExecPS2("rom0:OSDSYS", 0, NULL); - SleepThread(); - } - else if(selected == 0) - { - strcat(model, "50"); - *isSlim = 0; - } - else if(selected == 1) - { - strcat(model, "55"); - *isSlim = 0; - } - else if(selected == 2) - { - strcat(model, "70"); - *isSlim = 1; - } - else if(selected == 3) - { - strcat(model, "75"); - *isSlim = 1; - } - else if(selected == 4) - { - strcat(model, "77"); - *isSlim = 1; - } - else if(selected == 5) - { - strcat(model, "79"); - *isSlim = 1; - } - else if(selected == 6) - { - strcat(model, "90"); - *isSlim = 1; - } -} - -void selectRegion2(char isDex, char isSlim, char *model, uint8_t **region_params, uint8_t **region_ciphertext); -void selectRegion(char isDex, char isSlim, char *model, uint8_t **region_params, uint8_t **region_ciphertext) -{ - gsKit_clear(gsGlobal, Black); - - struct MENU menu; - menu.title = "Select model"; - menu.x_text = "X Select"; - menu.o_text = "O Exit"; - menu.option_count = 7; - - for (int i = 0; i < 6; i++) - { - char *option = malloc(20); - strcpy(option, model); - menu.options[i] = option; - } - - strcat((char *) menu.options[0], "000 - Japan"); - strcat((char *) menu.options[1], "001 - USA"); - strcat((char *) menu.options[2], "002 - Oceania"); - strcat((char *) menu.options[3], "003 - UK"); - strcat((char *) menu.options[4], "004 - Europe"); - strcat((char *) menu.options[5], "005 - Korea"); - menu.options[6] = "More"; - - int selected = drawMenu(&menu); - - for (int i = 0; i < 6; i++) - free((char *) menu.options[i]); - - if (selected == -1) - { - ResetIOP(); - LoadExecPS2("rom0:OSDSYS", 0, NULL); - SleepThread(); - } - else if(selected == 0) - { - strcat(model, "000"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_japan; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_japan_cex; - } - else if(selected == 1) - { - strcat(model, "001"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_usa; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_usa_cex; - } - else if(selected == 2) - { - strcat(model, "002"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_oceania; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_oceania_cex; - } - else if(selected == 3) - { - strcat(model, "003"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_europe; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_europe_cex; - } - else if(selected == 4) - { - strcat(model, "004"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_europe; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_europe_cex; - } - else if(selected == 5) - { - strcat(model, "005"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_korea; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_korea_cex; - } - else if(selected == 6) - { - return selectRegion2(isDex, isSlim, model, region_params, region_ciphertext); - } -} - -void selectRegion2(char isDex, char isSlim, char *model, uint8_t **region_params, uint8_t **region_ciphertext) -{ - gsKit_clear(gsGlobal, Black); - - struct MENU menu; - menu.title = "Select model"; - menu.x_text = "X Select"; - menu.o_text = "O Exit"; - menu.option_count = (isSlim ? 7 : 6); - - for (int i = 1; i < (isSlim ? 7 : 6); i++) - { - char *option = malloc(20); - strcpy(option, model); - menu.options[i] = option; - } - - menu.options[0] = "Back"; - strcat((char *) menu.options[1], "006 - Asia"); - strcat((char *) menu.options[2], "007 - Tawain"); - strcat((char *) menu.options[3], "008 - Russia"); - if (!isSlim) - { - strcat((char *) menu.options[4], "009 - China"); - strcat((char *) menu.options[5], "011 - Mexico"); - } - else - { - strcat((char *) menu.options[4], "010 - ???"); - strcat((char *) menu.options[5], "011 - ???"); - strcat((char *) menu.options[6], "012 - ???"); - } - - int selected = drawMenu(&menu); - - for (int i = 1; i < (isSlim ? 7 : 6); i++) - free((char *) menu.options[i]); - - if (selected == -1) - { - ResetIOP(); - LoadExecPS2("rom0:OSDSYS", 0, NULL); - SleepThread(); - } - else if(selected == 0) - { - return selectRegion(isDex, isSlim, model, region_params, region_ciphertext); - } - else if(selected == 1) - { - strcat(model, "006"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_asia; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_asia_cex; - } - else if(selected == 2) - { - strcat(model, "007"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_tawain; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_asia_cex; - } - else if(selected == 3) - { - strcat(model, "008"); - sum_buffer((uint8_t *) model, 18); - if (isSlim) - *region_params = region_params_russia; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_russia_cex; - } - else if(selected == 4) - { - if (!isSlim) - { - strcat(model, "009"); - sum_buffer((uint8_t *) model, 18); - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_china_cex; - } - else - { - strcat(model, "010"); - sum_buffer((uint8_t *) model, 18); - *region_params = region_params_usa; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_usa_cex; - } - } - else if(selected == 5) - { - if (!isSlim) - { - strcat(model, "011"); - sum_buffer((uint8_t *) model, 18); - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_mexico_cex; - } - else - { - strcat(model, "011"); - sum_buffer((uint8_t *) model, 18); - *region_params = region_params_usa; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_usa_cex; - } - } - else if(selected == 6) - { - strcat(model, "012"); - sum_buffer((uint8_t *) model, 18); - *region_params = region_params_usa; - if (isDex) - *region_ciphertext = region_ciphertext_dex; - else - *region_ciphertext = region_ciphertext_usa_cex; - } -} - -void setRegion(char *isDex) -{ - selectCexDex(isDex); - char isSlim = 0; - char model[18]; - selectModel(*isDex, &isSlim, model); - uint8_t *region_params = 0; - uint8_t *region_ciphertext = 0; - selectRegion(*isDex, isSlim, model, ®ion_params, ®ion_ciphertext); - - write_region(region_params, (uint8_t *) model, region_ciphertext); -} - -uint8_t *frames[] = { - &frame_001, &frame_002, &frame_003, &frame_004, &frame_005, &frame_006, &frame_007, &frame_008, - &frame_009, &frame_010, &frame_011, &frame_012, &frame_013, &frame_014, &frame_015, &frame_016, - &frame_017, &frame_018, &frame_019, &frame_020, &frame_021, &frame_022, &frame_023, &frame_024, - &frame_025, &frame_026, &frame_027, &frame_028, &frame_029, &frame_030, &frame_031, &frame_032, - &frame_033, &frame_034, &frame_035, &frame_036, &frame_037, &frame_038, &frame_039, &frame_040, - &frame_041, &frame_042, &frame_043, &frame_044, &frame_045, &frame_046, &frame_047, &frame_048, - &frame_049, &frame_050, &frame_051, &frame_052, &frame_053, &frame_054, &frame_055, &frame_056, - &frame_057, &frame_058, &frame_059, &frame_060, &frame_061, &frame_062 -}; - -void drawLogoFrame(uint8_t frame, char *text2) -{ - gsKit_clear(gsGlobal, Black); - - struct GSTEXTURE_holder *logoTextures = drawImage((gsGlobal->Width - 480) / 2, (gsGlobal->Height - 270) / 2, 480, 270, frames[frame]); - - char text[] = "MechaPwn"; - int x, y; - getTextSize(42, text, &x, &y); - y += 42; - struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - 270) / 2 - 50, 42, 0xFFFFFF, text); - - int x2, y2; - getTextSize(42, text2, &x2, &y2); - y2 += 42; - struct GSTEXTURE_holder *text2Textures = draw_text((gsGlobal->Width - x2) / 2, (gsGlobal->Height - 270) / 2 + 270, 42, 0xFFFFFF, text2); - - drawFrame(); - - freeGSTEXTURE_holder(text2Textures); - freeGSTEXTURE_holder(textTextures); - freeGSTEXTURE_holder(logoTextures); -} - -void drawLogo() -{ - uint8_t frame = 0; - while(!MassCheck()) - { - drawLogoFrame(frame++, "Waiting for USB drive..."); - - if (frame >= 62) - frame = 0; - } - - while (1) - { - drawLogoFrame(frame++, "Press X to continue."); - - if (frame >= 62) - frame = 0; - - u32 new_pad = ReadCombinedPadStatus(); - - if(new_pad & PAD_CROSS) - { - break; - } - } -} - -char backupNVM() -{ - FILE *f = fopen("mass:/nvm.bin", "rb"); - if (f) - { - fclose(f); - gsKit_clear(gsGlobal, Black); - - struct MENU menu; - menu.title = "An NVM backup found"; - menu.x_text = "X Select"; - menu.o_text = "O Exit"; - menu.option_count = 2; - - menu.options[0] = "Create a new backup"; - menu.options[1] = "Keep the current backup"; - - int selected = drawMenu(&menu); - - if (selected == -1) - { - ResetIOP(); - LoadExecPS2("rom0:OSDSYS", 0, NULL); - SleepThread(); - } - else if(selected == 1) - { - return 1; - } - } - - f = fopen("mass:/nvm.bin", "wb"); - if (!f) - { - gsKit_clear(gsGlobal, Black); - - char text[] = "Failed to open nvm.bin!"; - - int x, y; - getTextSize(42, text, &x, &y); - y += 42; - - struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, 42, 0xFFFFFF, text); - drawFrame(); - freeGSTEXTURE_holder(textTextures); - return 0; - } - - int x, y; - getTextSize(42, "Backing up to nvm.bin...", &x, &y); - y += 42; - - gsKit_clear(gsGlobal, Black); - struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, 42, 0xFFFFFF, "Backing up to nvm.bin..."); - drawFrame(); - freeGSTEXTURE_holder(textTextures); - - for (int i = 0; i < 0x200; i++) - { - uint16_t data; - if (!ReadNVM(i, &data)) - break; - fwrite(&data, 1, 2, f); - } - - fclose(f); - - return 1; -} - -char applyPatches(char isDex) -{ - uint8_t build_date[5]; - getMechaBuildDate(build_date); - - char applyForceUnlock = 0; - const uint8_t *force_unlock = getForceUnlock(build_date); - - if (isDex && force_unlock) - { - gsKit_clear(gsGlobal, Black); - - struct MENU menu; - menu.title = "Install force unlock?"; - menu.x_text = "X Select"; - menu.o_text = "O Exit"; - menu.option_count = 2; - - menu.options[0] = "No"; - menu.options[1] = "Yes"; - - int selected = drawMenu(&menu); - if (selected == -1) - { - ResetIOP(); - LoadExecPS2("rom0:OSDSYS", 0, NULL); - SleepThread(); - } - else if (selected == 1) - { - applyForceUnlock = 1; - } - } - - if (applyForceUnlock) - { - int x, y; - getTextSize(42, "Applying force unlock...", &x, &y); - y += 42; - - gsKit_clear(gsGlobal, Black); - struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, 42, 0xFFFFFF, "Applying force unlock..."); - drawFrame(); - freeGSTEXTURE_holder(textTextures); - - for (int i = 0; i < 112; i++) - { - if (!WriteNVM(400 + i, *(uint16_t*) &force_unlock[i * 2])) - break; - } - - } - else - { - FILE *f = fopen("mass:/nvm.bin", "rb"); - if (!f) - { - gsKit_clear(gsGlobal, Black); - - char text[] = "Failed to open nvm.bin!"; - - int x, y; - getTextSize(42, text, &x, &y); - y += 42; - - struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, 42, 0xFFFFFF, text); - drawFrame(); - freeGSTEXTURE_holder(textTextures); - return 0; - } - - int x, y; - getTextSize(42, "Restoring patches...", &x, &y); - y += 42; - - gsKit_clear(gsGlobal, Black); - struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, 42, 0xFFFFFF, "Restoring patches..."); - drawFrame(); - freeGSTEXTURE_holder(textTextures); - - fseek(f, 400 * 2, SEEK_SET); - for (int i = 0; i < 112; i++) - { - - uint16_t data; - fread(&data, 1, 2, f); - if (!WriteNVM(400 + i, data)) - break; - } - - fclose(f); - } - return 1; -} - -uint8_t *getPowerTexture() -{ - char model_number[18]; - for (int i = 0; i < 18; i += 2) - if (!ReadNVM(216 + i / 2, (uint16_t *) &model_number[i])) - break; - - if ( - memcmp(model_number, "SCPH-9", 6) == 0 || - memcmp(model_number, "DTL-H9", 6) == 0 - ) - return &pwr90k; - - if ( - memcmp(model_number, "SCPH-7", 6) == 0 || - memcmp(model_number, "DTL-H7", 6) == 0 - ) - return &pwr70k; - - return &pwr50k; -} - -void checkUnsupportedVersion() -{ - uint8_t version[3]; - uint8_t build_date[5]; - if (!getMechaVersion(version) || !getMechaBuildDate(build_date)) - { - gsKit_clear(gsGlobal, Black); - - struct GSTEXTURE_holder *errorTextures = draw_text(10, 200, 42, 0xFFFFFF, "This MechaCon isn't supported!\n"); - - drawFrame(); - - freeGSTEXTURE_holder(errorTextures); - - SleepThread(); - return; - } - - - const uint8_t *patch = getPatch(build_date); - if (patch == 0) - { - gsKit_clear(gsGlobal, Black); - - struct GSTEXTURE_holder *versionTextures = ui_printf(10, 100, 42, 0xFFFFFF, "Mecha version: %d.%02d\n", version[1], version[2]); - struct GSTEXTURE_holder *buildTextures = ui_printf(10, 150, 42, 0xFFFFFF, "Mecha build date: 20%02x/%02x/%02x %02x:%02x\n", build_date[0], build_date[1], build_date[2], build_date[3], build_date[4]); - - struct GSTEXTURE_holder *errorTextures = draw_text(10, 200, 42, 0xFFFFFF, "This MechaCon isn't supported!\n"); - - drawFrame(); - - freeGSTEXTURE_holder(versionTextures); - freeGSTEXTURE_holder(buildTextures); - freeGSTEXTURE_holder(errorTextures); - - SleepThread(); - return; - } -} - -char isPatchAlreadyInstalled() -{ - uint8_t build_date[5]; - getMechaBuildDate(build_date); - - uint8_t current_patch[224]; - - for (int i = 0; i < 112; i++) - { - if (!ReadNVM(400 + i, (uint16_t *) ¤t_patch[i * 2])) - break; - } - - const uint8_t *patch = getPatch(build_date); - - return memcmp(current_patch, patch, 224) == 0; -} - -char restoreBackup() -{ - FILE *f = fopen("mass:/nvm.bin", "rb"); - if (!f) - { - gsKit_clear(gsGlobal, Black); - - char text[] = "Failed to open nvm.bin!"; - - int x, y; - getTextSize(42, text, &x, &y); - y += 42; - - struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, 42, 0xFFFFFF, text); - drawFrame(); - freeGSTEXTURE_holder(textTextures); - return 0; - } - - int x, y; - getTextSize(42, "Restoring backup...", &x, &y); - y += 42; - - gsKit_clear(gsGlobal, Black); - struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, 42, 0xFFFFFF, "Restoring backup..."); - drawFrame(); - freeGSTEXTURE_holder(textTextures); - - for (int i = 0; i < 0x200; i++) - { - - uint16_t data; - fread(&data, 1, 2, f); - if (!WriteNVM(i, data)) - break; - } - - fclose(f); - return 1; -} - -int main() -{ - init_ui(); - - gsKit_mode_switch(gsGlobal, GS_ONESHOT); - - gsKit_clear(gsGlobal, Black); - - struct GSTEXTURE_holder *loadingTextures = draw_text(-10, -74, 42, 0xFFFFFF, "Loading..."); - drawFrame(); - freeGSTEXTURE_holder(loadingTextures); - - ResetIOP(); - - sbv_patch_enable_lmb(); - sbv_patch_disable_prefix_check(); - sbv_patch_fileio(); - - SifExecModuleBuffer(&iomanX, size_iomanX, 0, NULL, NULL); - SifExecModuleBuffer(&fileXio, size_fileXio, 0, NULL, NULL); - SifExecModuleBuffer(&freesio2, size_freesio2, 0, NULL, NULL); - SifExecModuleBuffer(&freepad, size_freepad, 0, NULL, NULL); - SifExecModuleBuffer(&mcman, size_mcman, 0, NULL, NULL); - SifExecModuleBuffer(&mcserv, size_mcserv, 0, NULL, NULL); - SifExecModuleBuffer(&USBD, size_USBD, 0, NULL, NULL); - SifExecModuleBuffer(&USBHDFSD, size_USBHDFSD, 0, NULL, NULL); - SifExecModuleBuffer(&MECHAPROXY_irx, size_MECHAPROXY_irx, 0, NULL, NULL); - SifExecModuleBuffer(&MASSWATCHER_irx, size_MASSWATCHER_irx, 0, NULL, NULL); - - MechaInit(); - MassInit(); - - mcInit(MC_TYPE_XMC); - - PadInitPads(); - - // --- - - drawLogo(); - - checkUnsupportedVersion(); - - uint8_t *powerTexture = getPowerTexture(); - - char rerun = 0; - if (!IsNVMUnlocked()) - { - rerun = 1; - if (!isPatchAlreadyInstalled()) - { - if (backupNVM()) - unlockNVM(); - } - } - else - { - gsKit_clear(gsGlobal, Black); - - struct MENU menu; - menu.title = "MechaPwn"; - menu.x_text = "X Select"; - menu.o_text = "O Exit"; - menu.option_count = 2; - - menu.options[0] = "Change region"; - menu.options[1] = "Restore NVM backup"; - - int selected = drawMenu(&menu); - - if (selected == -1) - { - ResetIOP(); - LoadExecPS2("rom0:OSDSYS", 0, NULL); - SleepThread(); - } - else if(selected == 0) - { - char isDex = 0; - setRegion(&isDex); - applyPatches(isDex); - } - else if(selected == 1) - { - restoreBackup(); - } - } - - gsKit_clear(gsGlobal, Black); - - struct GSTEXTURE_holder *imageTextures = drawImage((gsGlobal->Width - 400) / 2, (gsGlobal->Height - (225 + 60)) / 2, 400, 225, powerTexture); - - const char *text = "Unplug the power cord."; - int x, y; - getTextSize(42, text, &x, &y); - y += 42; - struct GSTEXTURE_holder *unplugTextures = draw_text((gsGlobal->Width - x) / 2, ((gsGlobal->Height - (225 + 60)) / 2) + 225, 42, 0xFFFFFF, text); - - struct GSTEXTURE_holder *rerunTextures = 0; - if (rerun) - { - const char *text = "Run MechaPwn again."; - int x, y; - getTextSize(42, text, &x, &y); - y += 42; - rerunTextures = draw_text((gsGlobal->Width - x) / 2, ((gsGlobal->Height - (195)) / 2) + 225, 42, 0xFFFFFF, text); - } - - drawFrame(); - if (rerunTextures) - freeGSTEXTURE_holder(rerunTextures); - freeGSTEXTURE_holder(unplugTextures); - freeGSTEXTURE_holder(imageTextures); - - - // --- - - SleepThread(); - - return 0; -} +/* + * Copyright (c) 2021 MechaResearch + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mecha.h" +#include "exploit.h" +#include "pad.h" +#include "binaries.h" +#include "ui.h" +#include "mass.h" + +static unsigned int big_size = 50, reg_size = 36; +// TODO: store existing areas on nvram on boot +static unsigned int IsKnownconsole = 0; + +static void ResetIOP() +{ + SifInitRpc(0); + while (!SifIopReset("", 0)) + { + }; + while (!SifIopSync()) + { + }; + SifInitRpc(0); + SifLoadFileInit(); +} + +char unlockNVM() +{ + uint8_t version[4]; + getMechaVersion(version); + + uint8_t build_date[5]; + getMechaBuildDate(build_date); + + gsKit_clear(gsGlobal, Black); + + struct GSTEXTURE_holder *versionTextures = ui_printf(8, 8 + big_size + big_size / 2 + 0 * (reg_size + 4), reg_size, 0xFFFFFF, "Mecha version: %d.%02d\n", version[1], (version[2] | 1) - 1); + struct GSTEXTURE_holder *buildTextures = ui_printf(8, 8 + big_size + big_size / 2 + 1 * (reg_size + 4), reg_size, 0xFFFFFF, "Mecha build date: 20%02x/%02x/%02x %02x:%02x\n", build_date[0], build_date[1], build_date[2], build_date[3], build_date[4]); + struct GSTEXTURE_holder *exploitTextures = draw_text(8, 8 + big_size + big_size / 2 + 2 * (reg_size + 4), reg_size, 0xFFFFFF, "Press O to unlock nvram.\n"); + struct GSTEXTURE_holder *exitTextures = draw_text(8, 8 + big_size + big_size / 2 + 3 * (reg_size + 4), reg_size, 0xFFFFFF, "Press X to exit.\n"); + + drawFrame(); + + while (1) + { + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_CIRCLE) + { + break; + } + else if (new_pad & PAD_CROSS) + { + gsKit_clear(gsGlobal, Black); + ResetIOP(); + Exit(0); + + return 0; + } + } + + // TODO: check original patch before, so it will be possible to restore it + const uint8_t *patch = getPatch(build_date); + if (!installPatch(patch)) + { + struct GSTEXTURE_holder *errorTextures = draw_text(8, 8 + big_size + big_size / 2 + 4 * (reg_size + 4), reg_size, 0xFFFFFF, "Failed to install unlock patch.\n"); + + drawFrame(); + + freeGSTEXTURE_holder(versionTextures); + if (getMechaBuildDate(build_date)) + freeGSTEXTURE_holder(buildTextures); + freeGSTEXTURE_holder(exploitTextures); + freeGSTEXTURE_holder(exitTextures); + freeGSTEXTURE_holder(errorTextures); + + return 0; + } + + freeGSTEXTURE_holder(versionTextures); + if (getMechaBuildDate(build_date)) + freeGSTEXTURE_holder(buildTextures); + freeGSTEXTURE_holder(exploitTextures); + freeGSTEXTURE_holder(exitTextures); + + return 1; +} + +struct MENU +{ + const char *title; + const char *x_text; + const char *o_text; + uint8_t option_count; + const char *options[10]; +}; + +int drawMenu(struct MENU *menu) +{ + int selected_menu = 0; + gsKit_clear(gsGlobal, Black); + + while (1) + { + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_UP) + { + selected_menu--; + } + else if (new_pad & PAD_DOWN) + { + selected_menu++; + } + else if (new_pad & PAD_CIRCLE) + { + return -1; + } + else if (new_pad & PAD_CROSS) + { + return selected_menu; + } + + if (selected_menu < 0) + selected_menu = menu->option_count - 1; + else if (selected_menu > menu->option_count - 1) + selected_menu = 0; + + gsKit_clear(gsGlobal, Black); + + int title_x, title_y; + getTextSize(big_size, menu->title, &title_x, &title_y); + + struct GSTEXTURE_holder *TitleTexture = draw_text((gsGlobal->Width - title_x) / 2, 8, big_size, 0xFFFFFF, menu->title); + struct GSTEXTURE_holder *oTexture = draw_text(8, -reg_size - 8, reg_size, 0xFFFFFF, menu->o_text); + struct GSTEXTURE_holder *xTexture = draw_text(-8, -reg_size - 8, reg_size, 0xFFFFFF, menu->x_text); + + struct GSTEXTURE_holder *menus[256]; + memset(menus, 0, sizeof(menus)); + + for (int i = 0; i < menu->option_count; i++) + { + int menu_x, menu_y; + getTextSize(reg_size, menu->options[i], &menu_x, &menu_y); + + menus[i] = draw_text((gsGlobal->Width - menu_x) / 2, 8 + big_size + big_size / 2 + i * (reg_size + 4), reg_size, selected_menu == i ? 0xFF6040 : 0xFFFFFF, menu->options[i]); + } + + drawFrame(); + + for (int i = 0; i < 256; i++) + if (menus[i]) + freeGSTEXTURE_holder(menus[i]); + + freeGSTEXTURE_holder(xTexture); + freeGSTEXTURE_holder(oTexture); + freeGSTEXTURE_holder(TitleTexture); + } +} + +uint8_t pal_defaults[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50}; +uint8_t ntsc_defaults[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40}; + +// HKkorJAG +// |||||||| +// |||||||G - rom1:DVDVER last byte (only in PS3) (possible values: " UEAGDCM", space symbol for Japan) +// ||||||A - rom1:DVDID last byte (possible values: "JUEAORCM") +// |||||J - rom0:VERSTR (0x22 byte: "System ROM Version 5.0 06/23/03 J") (possible values: "JAE") ps1 games, best region - A (no restrictions) +// |Kkor - rom0:OSDVER (5-8th byte) ("0190Csch"), allows to change console language set, possible values: Jjpn, Aeng, Eeng, Heng, Reng, Csch, Kkor, Htch, Aspa +// H - rom0:ROMVER (4th byte 0220HD20060905) (possible values: "JAEHC") ps2 games, best region - A (no restrictions) +uint8_t region_keyseed[] = {0x4d, 0x65, 0x63, 0x68, 0x61, 0x50, 0x77, 0x6e, 0x00, 0xec}; // MechaPwn +00 EC +// below will work on any unit, however will be about 7 seconds slower than matching region +// uint8_t region_ciphertext_dex[] = {0x05, 0x0D, 0x36, 0x04, 0x6F, 0x69, 0xB6, 0x76, 0x00, 0xAF}; // Region 00130000 + +// 0 - Japan +uint8_t region_params_japan[] = {0x4a, 0x4a, 0x6a, 0x70, 0x6e, 0x4a, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00}; // JJjpnJJ +uint8_t region_ciphertext_japan_cex[] = {0xf1, 0xef, 0x50, 0xec, 0x1c, 0x2e, 0xc5, 0x69, 0x00, 0x6b}; // Region 00020001 +uint8_t region_ciphertext_japan_dex[] = {0x8C, 0x28, 0x16, 0x47, 0x22, 0x45, 0x77, 0x9C, 0x00, 0x74}; // Region 00130001 + +// 1 - USA +uint8_t region_params_usa[] = {0x41, 0x41, 0x65, 0x6e, 0x67, 0x41, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00}; // AAengAU +uint8_t region_ciphertext_usa_cex[] = {0xb8, 0x42, 0xd5, 0xbc, 0x53, 0xa1, 0x96, 0xe6, 0x00, 0x04}; // Region 00020002 +uint8_t region_ciphertext_usa_dex[] = {0x63, 0xA8, 0x35, 0x2F, 0xDA, 0x53, 0xB8, 0x25, 0x00, 0x86}; // Region 00130002 + +// 2 - Oceania +uint8_t region_params_oceania[] = {0x45, 0x45, 0x65, 0x6e, 0x67, 0x45, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00}; // EEengEO +uint8_t region_ciphertext_oceania_cex[] = {0x64, 0xaa, 0x23, 0x25, 0x28, 0x5c, 0x14, 0xf3, 0x00, 0x1e}; // Region 00020008 +uint8_t region_ciphertext_oceania_dex[] = {0x9F, 0x1F, 0x8A, 0x15, 0x7D, 0x7C, 0x47, 0xF8, 0x00, 0x6A}; // Region 00130008 + + +// 3 - UK +// same as europe + +// 4 - Europe +uint8_t region_params_europe[] = {0x45, 0x45, 0x65, 0x6e, 0x67, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00}; // EEengEE +uint8_t region_ciphertext_europe_cex[] = {0x54, 0x88, 0x4f, 0x90, 0x76, 0x4d, 0xcb, 0xeb, 0x00, 0xcb}; // Region 00020004 +uint8_t region_ciphertext_europe_dex[] = {0x1D, 0xF2, 0xB6, 0x31, 0x21, 0xCE, 0x9C, 0x2F, 0x00, 0x4F}; // Region 00130004 + +// 5 - Korea +uint8_t region_params_korea[] = {0x48, 0x4b, 0x6b, 0x6f, 0x72, 0x4a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00}; // HKkorJA +// region_ciphertext is same as asia + + +// 6 - Asia +uint8_t region_params_asia[] = {0x48, 0x48, 0x65, 0x6e, 0x67, 0x4a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00}; // HHengJA +uint8_t region_ciphertext_asia_cex[] = {0x2a, 0xf0, 0x38, 0x2d, 0xef, 0xe5, 0x48, 0xa4, 0x00, 0xc0}; // Region 00020010 +uint8_t region_ciphertext_asia_dex[] = {0xEE, 0x92, 0xCC, 0x9E, 0xEA, 0x1A, 0xA9, 0x12, 0x00, 0x56}; // Region 00130010 + +// 7 - Taiwan +uint8_t region_params_taiwan[] = {0x48, 0x48, 0x74, 0x63, 0x68, 0x4a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00}; // HHtchJA +// region_ciphertext is same as asia + +// 8 - Russia +uint8_t region_params_russia[] = {0x45, 0x52, 0x65, 0x6e, 0x67, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00}; // ERengER +uint8_t region_ciphertext_russia_cex[] = {0x3e, 0x11, 0xc1, 0xbb, 0xfb, 0x26, 0x2b, 0x4c, 0x00, 0x9c}; // Region 00020020 +uint8_t region_ciphertext_russia_dex[] = {0xA1, 0x9D, 0xC3, 0x55, 0x8A, 0x71, 0x4D, 0xED, 0x00, 0x74}; // Region 00130020 + +// 9 - China +uint8_t region_params_china[] = {0x43, 0x43, 0x73, 0x63, 0x68, 0x4A, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; // CCschJC +uint8_t region_ciphertext_china_cex[] = {0x0f, 0x5d, 0xb8, 0xa2, 0x9d, 0x85, 0xcc, 0x76, 0x00, 0xd5}; // Region 00020040 +uint8_t region_ciphertext_china_dex[] = {0x94, 0x05, 0x23, 0xFE, 0xB3, 0xD1, 0x9E, 0x9B, 0x00, 0x88}; // Region 00130040 + +// 11 - Mexico / ??? +uint8_t region_params_mexico[] = {0x41, 0x41, 0x73, 0x70, 0x61, 0x41, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00}; // AAspaAM +uint8_t region_ciphertext_mexico_cex[] = {0x35, 0x1a, 0x92, 0x9a, 0x05, 0x5b, 0xdc, 0x40, 0x00, 0x08}; // Region 00020080 +uint8_t region_ciphertext_mexico_dex[] = {0x75, 0xED, 0x46, 0x5D, 0x9E, 0xC9, 0xD9, 0x1E, 0x00, 0x9C}; // Region 00130080 + +// 12 - ??? + +void sum_buffer(uint8_t *buffer, int length) +{ + uint8_t sum = 0; + for (int i = 0; i < length - 2; i++) + sum += buffer[i]; + buffer[length - 2] = 0; + buffer[length - 1] = ~sum; +} + +void sum_buffer2(uint8_t *buffer, int length) +{ + uint8_t sum = 0; + for (int i = 0; i < length - 1; i++) + sum += buffer[i]; + buffer[length - 1] = sum; +} + +char write_region(uint8_t *region_params, uint8_t *region_ciphertext, uint8_t *video_config) +{ + uint8_t version[4]; + uint8_t isSlim = 0; + getMechaVersion(version); + if (version[1] == 6) + isSlim = 1; + + if (isSlim && video_config) + { + // PAL/NTSC selector + for (int i = 0; i < 16; i += 2) + if (!WriteNVM(320 + i / 2, *(uint16_t *)&video_config[i])) + break; + + for (int i = 0; i < 12; i += 2) + if (!WriteNVM(192 + i / 2, *(uint16_t *)®ion_params[i])) + break; + } + + if (region_ciphertext) + { + for (int i = 0; i < 10; i += 2) + if (!WriteNVM(227 + i / 2, *(uint16_t *)®ion_keyseed[i])) + break; + + for (int i = 0; i < 10; i += 2) + if (!WriteNVM(232 + i / 2, *(uint16_t *)®ion_ciphertext[i])) + break; + } + + return 1; +} + +void selectCexDex(char *isDex) +{ + gsKit_clear(gsGlobal, Black); + + uint8_t version[4]; + uint8_t isSlim = 0; + getMechaVersion(version); + if (version[1] == 6) + isSlim = 1; + + struct MENU menu; + menu.title = "Select console type"; + menu.x_text = "X Select"; + menu.o_text = "O Exit"; + menu.option_count = 1; + if (isSlim) + { + menu.option_count = 2; + menu.options[1] = "CEX (retail)"; + } + menu.options[0] = "Retail-DEX"; + + int selected = drawMenu(&menu); + + gsKit_clear(gsGlobal, Black); + + drawFrame(); + + if (selected == -1) + { + ResetIOP(); + Exit(0); + SleepThread(); + } + + *isDex = selected == 0; +} + +void selectRegion(char isDex, uint8_t **region_params, uint8_t **region_ciphertext, uint8_t **video_config) +{ + gsKit_clear(gsGlobal, Black); + + int selected = 0; + uint8_t version[4]; + uint8_t isSlim = 0; + uint8_t isDeckard = 0; + getMechaVersion(version); + if (version[1] == 6) + isSlim = 1; + if ((version[1] == 6) && (version[2] >= 6)) + isDeckard = 1; + + if (isSlim) + { + struct MENU menu; + menu.title = "Select region (OSD/DVD)"; + menu.x_text = "X Select"; + menu.o_text = "O Exit"; + + menu.option_count = 9; + menu.options[0] = "USA (Multi-7)"; // Aeng*U + menu.options[1] = "Asia (Multi-7)"; // Heng*A + menu.options[2] = "Korea"; // Kkor*A + menu.options[3] = "Taiwan"; // Htch*A + menu.options[4] = "Japan"; // Jjpn*J + menu.options[5] = "Mexico (Multi-7)"; // Aspa*M + menu.options[6] = "Europe (Multi-7)"; // Eeng*E + menu.options[7] = "Oceania (Multi-7)"; // Eeng*O + menu.options[8] = "Russia"; // Reng*R + // menu.options[9] = "China"; // Csch*C // slim OSD will crash + + selected = drawMenu(&menu); + } + + if (selected == -1) + { + ResetIOP(); + Exit(0); + SleepThread(); + } + else + { + if (selected == 0) + { + *region_params = region_params_usa; + *region_ciphertext = isDex ? region_ciphertext_usa_dex : region_ciphertext_usa_cex; + *video_config = ntsc_defaults; + } + else if (selected == 1) + { + *region_params = region_params_asia; + *region_ciphertext = isDex ? region_ciphertext_asia_dex : region_ciphertext_asia_cex; + *video_config = ntsc_defaults; + } + else if (selected == 2) + { + *region_params = region_params_korea; + *region_ciphertext = isDex ? region_ciphertext_asia_dex : region_ciphertext_asia_cex; + *video_config = ntsc_defaults; + } + else if (selected == 3) + { + *region_params = region_params_taiwan; + *region_ciphertext = isDex ? region_ciphertext_asia_dex : region_ciphertext_asia_cex; + *video_config = ntsc_defaults; + } + else if (selected == 4) + { + *region_params = region_params_japan; + *region_ciphertext = isDex ? region_ciphertext_japan_dex : region_ciphertext_japan_cex; + *video_config = ntsc_defaults; + } + else if (selected == 5) + { + *region_params = region_params_mexico; + *region_ciphertext = isDex ? region_ciphertext_mexico_dex : region_ciphertext_mexico_cex; + *video_config = ntsc_defaults; + } + else if (selected == 6) + { + *region_params = region_params_europe; + *region_ciphertext = isDex ? region_ciphertext_europe_dex : region_ciphertext_europe_cex; + *video_config = pal_defaults; + } + else if (selected == 7) + { + *region_params = region_params_oceania; + *region_ciphertext = isDex ? region_ciphertext_oceania_dex : region_ciphertext_oceania_cex; + *video_config = pal_defaults; + } + else if (selected == 8) + { + *region_params = region_params_russia; + *region_ciphertext = isDex ? region_ciphertext_russia_dex : region_ciphertext_russia_cex; + *video_config = pal_defaults; + } + else if (selected == 9) + { + *region_params = region_params_china; + *region_ciphertext = isDex ? region_ciphertext_china_dex : region_ciphertext_china_cex; + *video_config = ntsc_defaults; + } + + if (isDex) + { + region_params[0][0] = 0x41; // A - PS2 disable checks + region_params[0][5] = 0x41; // A - PS1 disable checks + } + + if (!(isDeckard)) + { + int fd; + if ((fd = open("rom0:ROMVER", O_RDONLY)) >= 0) + { + char romver[16]; + read(fd, romver, sizeof(romver)); + close(fd); + + // ckeck romver 5th letter: JAEHC, compare with version[0] & 7 + // J - 0 + // A - 1, 7 + // E - 2, 3, 5 + // H - 4 + // C - 6 + if (romver[4] == 'J') + *region_ciphertext = isDex ? region_ciphertext_japan_dex : region_ciphertext_japan_cex; + else if (romver[4] == 'C') + *region_ciphertext = isDex ? region_ciphertext_china_dex : region_ciphertext_china_cex; + else if ((romver[4] == 'E') && ((version[0] & 7) == 3)) + *region_ciphertext = isDex ? region_ciphertext_oceania_dex : region_ciphertext_oceania_cex; + else if ((romver[4] == 'E') && ((version[0] & 7) == 5)) + *region_ciphertext = isDex ? region_ciphertext_russia_dex : region_ciphertext_russia_cex; + else if (romver[4] == 'E') + *region_ciphertext = isDex ? region_ciphertext_europe_dex : region_ciphertext_europe_cex; + else if ((romver[4] == 'A') && ((version[0] & 7) == 7)) + *region_ciphertext = isDex ? region_ciphertext_mexico_dex : region_ciphertext_mexico_cex; + else if (romver[4] == 'A') + *region_ciphertext = isDex ? region_ciphertext_usa_dex : region_ciphertext_usa_cex; + else if (romver[4] == 'H') + *region_ciphertext = isDex ? region_ciphertext_asia_dex : region_ciphertext_asia_cex; + } + } + } +} + +void setRegion(char *isDex) +{ + selectCexDex(isDex); + + uint8_t *region_params = 0; + uint8_t *region_ciphertext = 0; + uint8_t *video_config = 0; + selectRegion(*isDex, ®ion_params, ®ion_ciphertext, &video_config); + + write_region(region_params, region_ciphertext, video_config); +} + +uint8_t *frames[] = { + &frame_001, &frame_002, &frame_003, &frame_004, &frame_005, &frame_006, &frame_007, &frame_008, + &frame_009, &frame_010, &frame_011, &frame_012, &frame_013, &frame_014, &frame_015, &frame_016, + &frame_017, &frame_018, &frame_019, &frame_020, &frame_021, &frame_022, &frame_023, &frame_024, + &frame_025, &frame_026, &frame_027, &frame_028, &frame_029, &frame_030, &frame_031, &frame_032, + &frame_033, &frame_034, &frame_035, &frame_036, &frame_037, &frame_038, &frame_039, &frame_040, + &frame_041, &frame_042, &frame_043, &frame_044, &frame_045, &frame_046, &frame_047, &frame_048, + &frame_049, &frame_050, &frame_051, &frame_052, &frame_053, &frame_054, &frame_055, &frame_056, + &frame_057, &frame_058, &frame_059, &frame_060, &frame_061, &frame_062}; + +void drawLogoFrame(uint8_t frame, char *text2) +{ + gsKit_clear(gsGlobal, Black); + + struct GSTEXTURE_holder *logoTextures = drawImage((gsGlobal->Width - 480) / 2, (gsGlobal->Height - 270) / 2, 480, 270, frames[frame]); + + char text[] = "MechaPwn"; + int x, y; + getTextSize(big_size, text, &x, &y); + y += big_size; + struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - 270) / 2 - big_size - 8, big_size, 0xFFFFFF, text); + + int x2, y2; + getTextSize(big_size, text2, &x2, &y2); + y2 += big_size; + struct GSTEXTURE_holder *text2Textures = draw_text((gsGlobal->Width - x2) / 2, (gsGlobal->Height - 270) / 2 + 270, big_size, 0xFFFFFF, text2); + + drawFrame(); + + freeGSTEXTURE_holder(text2Textures); + freeGSTEXTURE_holder(textTextures); + freeGSTEXTURE_holder(logoTextures); +} + +void drawLogo() +{ + uint8_t frame = 0; + while (!MassCheck()) + { + drawLogoFrame(frame++, "Waiting for USB drive..."); + + if (frame >= 62) + frame = 0; + } + + while (1) + { + drawLogoFrame(frame++, "Press X to continue."); + + if (frame >= 62) + frame = 0; + + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_CROSS) + { + break; + } + } +} + +char backupNVM() +{ + // TODO: maybe save 2 backups? one to the memory card, ont ot the flash? + uint32_t serial[1]; + getSerial(serial); + uint8_t version[4]; + getMechaVersion(version); + + char nvm_path[256]; + sprintf(nvm_path, "mass:/nvm_%d.%02d_%07ld.bin", version[1], (version[2] | 1) - 1, serial[0]); + + FILE *f = fopen(nvm_path, "rb"); + if (f) + { + fseek(f, 0, SEEK_END); + int len = ftell(f); + fclose(f); + if (len == 1024) + return 1; + else + { + gsKit_clear(gsGlobal, Black); + + char text[] = "NVRAM backup is corrupted!"; + + int x, y; + getTextSize(reg_size, text, &x, &y); + y += reg_size; + + struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, text); + struct GSTEXTURE_holder *exitTextures = draw_text(8, 8 + big_size + big_size / 2 + 6 * (reg_size + 4), reg_size, 0xFFFFFF, "Press X to exit.\n"); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + freeGSTEXTURE_holder(exitTextures); + while (1) + { + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_CROSS) + { + ResetIOP(); + Exit(0); + SleepThread(); + } + } + return 0; + } + } + + int x, y; + getTextSize(reg_size, "Backing up NVRAM...", &x, &y); + y += reg_size; + + gsKit_clear(gsGlobal, Black); + struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, "Backing up NVRAM..."); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + + f = fopen(nvm_path, "wb"); + for (int i = 0; i < 0x200; i++) + { + uint16_t data; + if (!ReadNVM(i, &data)) + break; + fwrite(&data, 1, 2, f); + } + + // TODO: add more messages to the screen about backuping + fclose(f); + + return 1; +} + +char applyPatches(char isDex) +{ + uint8_t build_date[5]; + getMechaBuildDate(build_date); + + char applyOriginalPatch = 0; + char applyForceUnlock = 0; + const uint8_t *force_unlock = getForceUnlock(build_date); + const uint8_t *orig_patch = getOrigPatch(build_date); + + gsKit_clear(gsGlobal, Black); + + struct MENU menu; + menu.title = "Patch menu"; + menu.x_text = "X Select"; + menu.o_text = "O Exit"; + menu.option_count = 2; + + menu.options[0] = "Keep current patch"; + menu.options[1] = "Restore factory defaults"; + if (isDex && force_unlock) + { + menu.option_count = 3; + menu.options[2] = "Install force unlock"; + } + + int selected = drawMenu(&menu); + if (selected == -1) + { + ResetIOP(); + Exit(0); + SleepThread(); + } + else if (selected == 1) + applyOriginalPatch = 1; + else if (selected == 2) + applyForceUnlock = 1; + + if (applyOriginalPatch) + { + int x, y; + getTextSize(reg_size, "Applying factory defaults...", &x, &y); + y += reg_size; + + gsKit_clear(gsGlobal, Black); + struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, "Applying factory defaults..."); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + + for (int i = 0; i < 112; i++) + { + if (!WriteNVM(400 + i, *(uint16_t *)&orig_patch[i * 2])) + break; + } + } + else if (applyForceUnlock) + { + int x, y; + getTextSize(reg_size, "Applying force unlock...", &x, &y); + y += reg_size; + + gsKit_clear(gsGlobal, Black); + struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, "Applying force unlock..."); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + + for (int i = 0; i < 112; i++) + { + if (!WriteNVM(400 + i, *(uint16_t *)&force_unlock[i * 2])) + break; + } + } + else + { + uint32_t serial[1]; + getSerial(serial); + uint8_t version[4]; + getMechaVersion(version); + + char nvm_path[256]; + sprintf(nvm_path, "mass:/nvm_%d.%02d_%07ld.bin", version[1], (version[2] | 1) - 1, serial[0]); + FILE *f = fopen(nvm_path, "rb"); + if (!f) + { + gsKit_clear(gsGlobal, Black); + + char text[] = "Failed to open NVRAM backup!"; + + int x, y; + getTextSize(reg_size, text, &x, &y); + y += reg_size; + + struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, text); + struct GSTEXTURE_holder *exitTextures = draw_text(8, 8 + big_size + big_size / 2 + 6 * (reg_size + 4), reg_size, 0xFFFFFF, "Press X to exit.\n"); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + freeGSTEXTURE_holder(exitTextures); + while (1) + { + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_CROSS) + { + ResetIOP(); + Exit(0); + SleepThread(); + } + } + return 0; + } + else + { + fseek(f, 0, SEEK_END); + int len = ftell(f); + fclose(f); + if (len != 1024) + { + gsKit_clear(gsGlobal, Black); + + char text[] = "NVRAM backup is corrupted!"; + + int x, y; + getTextSize(reg_size, text, &x, &y); + y += reg_size; + + struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, text); + struct GSTEXTURE_holder *exitTextures = draw_text(8, 8 + big_size + big_size / 2 + 6 * (reg_size + 4), reg_size, 0xFFFFFF, "Press X to exit.\n"); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + freeGSTEXTURE_holder(exitTextures); + while (1) + { + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_CROSS) + { + ResetIOP(); + Exit(0); + SleepThread(); + } + } + return 0; + } + } + + int x, y; + getTextSize(reg_size, "Restoring patches...", &x, &y); + y += reg_size; + + gsKit_clear(gsGlobal, Black); + struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, "Restoring patches..."); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + + f = fopen(nvm_path, "rb"); + fseek(f, 400 * 2, SEEK_SET); + for (int i = 0; i < 112; i++) + { + + uint16_t data; + fread(&data, 1, 2, f); + if (!WriteNVM(400 + i, data)) + break; + } + + fclose(f); + } + return 1; +} + +uint8_t *getPowerTexture() +{ + uint8_t version[4]; + getMechaVersion(version); + uint16_t ModelId; + ReadNVM(0xF8, &ModelId); + + if (version[1] == 6) + { + if (ModelId < 0xd475) + return &pwr70k; // for all slims before 90k: 70k, 75k, 77k, 79k + else if ((ModelId == 0xd48f) || (ModelId == 0xd490)) + return &pwrtvcombo; + else + return &pwr90k; + } + else if (version[1] == 5) + { + if (version[2] == 10) + return &pwrpsx1; + else if (version[2] == 14) + return &pwrpsx2; + } + + return &pwr50k; +} + +char isPatchKnown() +{ + uint8_t build_date[5]; + uint8_t current_patch[224]; + char ret = 0; + for (int i = 0; i < 112; i++) + if (!ReadNVM(400 + i, (uint16_t *)¤t_patch[i * 2])) + break; + + getMechaBuildDate(build_date); + uint8_t *patch = (uint8_t *)getOrigPatch(build_date); + + if (patch) + { + ret = memcmp(current_patch, patch, 224) == 0; + free(patch); + patch = NULL; + if (!ret) + { + patch = (uint8_t *)getPatch(build_date); + if (patch) + { + ret = memcmp(current_patch, patch, 224) == 0; + free(patch); + patch = NULL; + if (!ret) + { + patch = (uint8_t *)getForceUnlock(build_date); + if (patch) + ret = memcmp(current_patch, orig_patch610_A, 224) == 0; + } + } + } + } + + return ret; +} + +void checkFMCB() +{ + uint8_t version[4]; + uint8_t isDeckard = 0; + getMechaVersion(version); + if ((version[1] == 6) && (version[2] >= 6)) + isDeckard = 1; + if (isDeckard) + { + // Check for NA FMCB folder on Deckard, this is minimal check + FILE *f = fopen("mc0:/BAEXEC-SYSTEM/osdmain.elf", "rb"); + if (f) // FMCB mc0 is ok, skipping + fclose(f); + else + { + f = fopen("mc1:/BAEXEC-SYSTEM/osdmain.elf", "rb"); + if (f) // FMCB mc1 is ok, skipping + fclose(f); + else + { + gsKit_clear(gsGlobal, Black); + int title_x, title_y; + getTextSize(big_size, "FMCB check", &title_x, &title_y); + + struct GSTEXTURE_holder *TitleTexture = draw_text((gsGlobal->Width - title_x) / 2, 8, big_size, 0xFFFFFF, "FMCB check"); + + struct GSTEXTURE_holder *errorTextures1 = draw_text(8, 8 + big_size + big_size / 2 + 0 * (reg_size + 4), reg_size, 0xFFFFFF, "FMCB Cross-region not found!!!\n"); + struct GSTEXTURE_holder *errorTextures2 = draw_text(8, 8 + big_size + big_size / 2 + 1 * (reg_size + 4), reg_size, 0xFFFFFF, "FMCB may stop to work after installation.\n"); + struct GSTEXTURE_holder *errorTextures3 = draw_text(8, 8 + big_size + big_size / 2 + 2 * (reg_size + 4), reg_size, 0xFFFFFF, "*Tuna FMCB will keep working.\n"); + struct GSTEXTURE_holder *continueTextures = draw_text(8, 8 + big_size + big_size / 2 + 6 * (reg_size + 4), reg_size, 0xFFFFFF, "Press O to continue.\n"); + struct GSTEXTURE_holder *exitTextures = draw_text(8, 8 + big_size + big_size / 2 + 7 * (reg_size + 4), reg_size, 0xFFFFFF, "Press X to exit.\n"); + drawFrame(); + + freeGSTEXTURE_holder(exitTextures); + freeGSTEXTURE_holder(continueTextures); + freeGSTEXTURE_holder(errorTextures3); + freeGSTEXTURE_holder(errorTextures2); + freeGSTEXTURE_holder(errorTextures1); + freeGSTEXTURE_holder(TitleTexture); + + while (1) + { + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_CIRCLE) + break; + else if (new_pad & PAD_CROSS) + { + gsKit_clear(gsGlobal, Black); + ResetIOP(); + Exit(0); + } + } + } + } + } +} + +void checkUnsupportedVersion() +{ + int fd; + uint8_t version[4]; + uint8_t build_date[5]; + char RealModelName[20]; + char color[20]; + struct GSTEXTURE_holder *versionTextures; + struct GSTEXTURE_holder *romverTextures; + struct GSTEXTURE_holder *buildTextures; + struct GSTEXTURE_holder *serialTextures; + struct GSTEXTURE_holder *ModelIDTextures; + struct GSTEXTURE_holder *modelnameTextures; + struct GSTEXTURE_holder *colorTextures; + // struct GSTEXTURE_holder *warnTextures1; + // struct GSTEXTURE_holder *warnTextures2; + + struct GSTEXTURE_holder *errorTextures; + + backupNVM(); + gsKit_clear(gsGlobal, Black); + + if (!getMechaVersion(version)) + { + errorTextures = draw_text(8, 8 + big_size + big_size / 2 + 5 * (reg_size + 4), reg_size, 0xFFFFFF, "This MechaCon isn't supported!\n"); + drawFrame(); + freeGSTEXTURE_holder(errorTextures); + SleepThread(); + return; + } + versionTextures = ui_printf(8, 8 + big_size + big_size / 2 + 0 * (reg_size + 4), reg_size, 0xFFFFFF, "Mecha version: %d.%02d\n", version[1], (version[2] | 1) - 1); + + if ((fd = open("rom0:ROMVER", O_RDONLY)) >= 0) + { + char romver[16]; + read(fd, romver, sizeof(romver)); + close(fd); + + romverTextures = ui_printf(8, 8 + big_size + big_size / 2 + 4 * (reg_size + 4), reg_size, 0xFFFFFF, "Romver: %s\n", romver); + } + + uint32_t serial[1]; + getSerial(serial); + serialTextures = ui_printf(8, 8 + big_size + big_size / 2 - 1 * (reg_size + 4), reg_size, 0xFFFFFF, "S/N: %07d\n", serial[0]); + + uint16_t ModelId; + if (version[1] < 4) + ReadNVM(0xE4, &ModelId); + else + ReadNVM(0xF8, &ModelId); + ModelIDTextures = ui_printf(8, 8 + big_size + big_size / 2 - 2 * (reg_size + 4), reg_size, 0xFFFFFF, "Model ID: 0x%X\n", ModelId); + + // ModelID whitelist + IsKnownconsole = 1; + sprintf(RealModelName, "???"); + // clang-format off + if (ModelId == 0xd200) sprintf(RealModelName, "DTL-H10000"); + else if (ModelId == 0xd201) sprintf(RealModelName, "SCPH-10000"); + else if (ModelId == 0xd202) sprintf(RealModelName, "SCPH-15000/18000"); + else if (ModelId == 0xd203) sprintf(RealModelName, "SCPH-30001"); + else if (ModelId == 0xd204) sprintf(RealModelName, "SCPH-30002/R"); + else if (ModelId == 0xd205) sprintf(RealModelName, "SCPH-30003/R"); + else if (ModelId == 0xd206) sprintf(RealModelName, "SCPH-30004/R"); + else if (ModelId == 0xd207) sprintf(RealModelName, "DTL-H30001"); + else if (ModelId == 0xd208) sprintf(RealModelName, "DTL-H30002"); + else if (ModelId == 0xd209) sprintf(RealModelName, "COH-H30000"); + else if (ModelId == 0xd20a) sprintf(RealModelName, "SCPH-18000"); + else if (ModelId == 0xd20b) sprintf(RealModelName, "COH-H31000"); + else if (ModelId == 0xd20c) sprintf(RealModelName, "SCPH-30000"); + else if (ModelId == 0xd20d) sprintf(RealModelName, "DTL-H30000"); + else if (ModelId == 0xd20e) sprintf(RealModelName, "COH-H31100"); + else if (ModelId == 0xd20f) sprintf(RealModelName, "SCPH-35001 GT"); + else if (ModelId == 0xd210) sprintf(RealModelName, "SCPH-35002 GT"); + else if (ModelId == 0xd211) sprintf(RealModelName, "SCPH-35003 GT"); + else if (ModelId == 0xd212) sprintf(RealModelName, "SCPH-35004 GT"); + else if (ModelId == 0xd213) sprintf(RealModelName, "SCPH-35000 GT"); + else if (ModelId == 0xd214) sprintf(RealModelName, "SCPH-30001/R"); + else if (ModelId == 0xd215) sprintf(RealModelName, "SCPH-30005 R"); + else if (ModelId == 0xd216) sprintf(RealModelName, "SCPH-30006 R"); + else if (ModelId == 0xd217) sprintf(RealModelName, "SCPH-39000"); + else if (ModelId == 0xd218) sprintf(RealModelName, "SCPH-39001"); + else if (ModelId == 0xd219) sprintf(RealModelName, "SCPH-39002"); + else if (ModelId == 0xd21a) sprintf(RealModelName, "SCPH-39003"); + else if (ModelId == 0xd21b) sprintf(RealModelName, "SCPH-39004"); + /* else if (ModelId == 0xd21c) sprintf(RealModelName, "SCPH-30007 R"); */ + else if (ModelId == 0xd21d) sprintf(RealModelName, "SCPH-37000 L"); + else if (ModelId == 0xd21e) sprintf(RealModelName, "SCPH-37000 B"); + else if (ModelId == 0xd21f) sprintf(RealModelName, "SCPH-39008"); + else if (ModelId == 0xd220) sprintf(RealModelName, "SCPH-39000 TB"); + else if (ModelId == 0xd221) sprintf(RealModelName, "SCPH-39000 RC"); + else if (ModelId == 0xd222) sprintf(RealModelName, "SCPH-39006"); + /* else if (ModelId == 0xd223) sprintf(RealModelName, "SCPH-39005"); + else if (ModelId == 0xd224) sprintf(RealModelName, "SCPH-39007"); */ + else if (ModelId == 0xd225) sprintf(RealModelName, "DTL-H10100"); + else if (ModelId == 0xd226) sprintf(RealModelName, "DTL-H30100"); + else if (ModelId == 0xd227) sprintf(RealModelName, "DTL-H30101"); + else if (ModelId == 0xd228) sprintf(RealModelName, "DTL-H30102"); + else if (ModelId == 0xd229) sprintf(RealModelName, "DTL-H30105"); + else if (ModelId == 0xd22a) sprintf(RealModelName, "SCPH-39000 S"); + else if (ModelId == 0xd22b) sprintf(RealModelName, "SCPH-39000 AQ"); + else if (ModelId == 0xd22c) sprintf(RealModelName, "SCPH-39000 SA"); + else if (ModelId == 0xd22d) sprintf(RealModelName, "SCPH-39010/N"); + // Deckard + // d300 = SCPH-50000, whats that? + else if (ModelId == 0xd301) sprintf(RealModelName, "DTL-H50000"); + else if (ModelId == 0xd302) sprintf(RealModelName, "DTL-H50001"); + else if (ModelId == 0xd303) sprintf(RealModelName, "DTL-H50002"); + else if (ModelId == 0xd304) sprintf(RealModelName, "DTL-H50009"); + // d305 - d31d ?? + else if (ModelId == 0xd31e) sprintf(RealModelName, "DTL-H70002"); + /* else if (ModelId == 0xd31f) sprintf(RealModelName, "DTL-H70011S ???"); + else if (ModelId == 0xd320) sprintf(RealModelName, "???"); + else if (ModelId == 0xd321) sprintf(RealModelName, "???"); */ + else if (ModelId == 0xd322) sprintf(RealModelName, "DTL-H75000A"); + /* else if (ModelId == 0xd323) sprintf(RealModelName, "???"); + else if (ModelId == 0xd324) sprintf(RealModelName, "???"); + else if (ModelId == 0xd325) sprintf(RealModelName, "???"); */ + else if (ModelId == 0xd326) sprintf(RealModelName, "DTL-H90000(a)"); + // d327-d37f + // X-chassis + else if (ModelId == 0xd380) sprintf(RealModelName, "DESR-7000"); + else if (ModelId == 0xd381) sprintf(RealModelName, "DESR-5000"); + else if (ModelId == 0xd382) sprintf(RealModelName, "DESR-7100"); + else if (ModelId == 0xd383) sprintf(RealModelName, "DESR-5100"); + else if (ModelId == 0xd384) sprintf(RealModelName, "DESR-5100/S"); + else if (ModelId == 0xd385) sprintf(RealModelName, "DESR-7500"); + else if (ModelId == 0xd386) sprintf(RealModelName, "DESR-5500"); + else if (ModelId == 0xd387) sprintf(RealModelName, "DESR-7700"); + else if (ModelId == 0xd388) sprintf(RealModelName, "DESR-5700"); + // d389 - d400 ?? + // H, I, J -chassis + /* else if (ModelId == 0xd400) sprintf(RealModelName, "SCPH-50001"); // 35: PX1, PX2, 27203531, 27203532 */ + else if (ModelId == 0xd401) sprintf(RealModelName, "SCPH-50001/N"); // 37: PX7, PX8, 27203731, 27203732 + else if (ModelId == 0xd402) sprintf(RealModelName, "SCPH-50010/N"); // ??: PU6 + else if (ModelId == 0xd403) sprintf(RealModelName, "SCPH-50000"); // 35: 27203500, 27203502 + else if (ModelId == 0xd404) sprintf(RealModelName, "SCPH-50000 MB/NH"); // 39, 43, 60: 27203900, 27203902, 27204302, 27206002 + else if (ModelId == 0xd405) sprintf(RealModelName, "SCPH-50002"); // 35: 27203591 + else if (ModelId == 0xd406) sprintf(RealModelName, "SCPH-50003"); // 35: 227203561 + else if (ModelId == 0xd407) sprintf(RealModelName, "SCPH-50004"); // 35: 227203551, 27203552 + else if (ModelId == 0xd408) sprintf(RealModelName, "SCPH-50002 SS"); // 40: 27204091, Silver Prestige Line + else if (ModelId == 0xd409) sprintf(RealModelName, "SCPH-50003 SS"); // 40: 27204061, Silver Prestige Line + else if (ModelId == 0xd40a) sprintf(RealModelName, "SCPH-50004 SS"); // 40: 27204051, 27204052, Silver Prestige Line + else if (ModelId == 0xd40b) sprintf(RealModelName, "SCPH-50001"); // 41: PX3, PX4, 27204131, 27204132 + else if (ModelId == 0xd40c) sprintf(RealModelName, "SCPH-50005/N"); // 37: 27203725 + else if (ModelId == 0xd40d) sprintf(RealModelName, "SCPH-50006"); // 35: 27203512, 27203518 + else if (ModelId == 0xd40e) sprintf(RealModelName, "SCPH-50007"); // 35: 27203516 + else if (ModelId == 0xd40f) sprintf(RealModelName, "SCPH-50008"); // 35: 27203581 + /* else if (ModelId == 0xd410) sprintf(RealModelName, "??? SCPH-50009 Black"); */ + else if (ModelId == 0xd411) sprintf(RealModelName, "SCPH-50000 NB"); // 45, 46, 54: 27204501, 27204502, 27204604, 27205402 + else if (ModelId == 0xd412) sprintf(RealModelName, "SCPH-50000 TSS"); // 40: 27204004 + else if (ModelId == 0xd413) sprintf(RealModelName, "SCPH-55000 GU"); // 67: 27206702 + else if (ModelId == 0xd414) sprintf(RealModelName, "SCPH-55000 GT"); // 47, 49: 27204704, 27204904 + else if (ModelId == 0xd415) sprintf(RealModelName, "SCPH-50009 SS"); // 37, 40: 27203720, 27204020 + else if (ModelId == 0xd416) sprintf(RealModelName, "SCPH-50003 AQ"); // 51: 27205161 + /* else if (ModelId == 0xd417) sprintf(RealModelName, "??? SCPH-55005 GT/N"); // 50: 27205025 */ + else if (ModelId == 0xd418) sprintf(RealModelName, "SCPH-55006 GT"); // 47: 27204718 + /* else if (ModelId == 0xd419) sprintf(RealModelName, "??? SCPH-55007 GT"); // 47: 27204716 */ + else if (ModelId == 0xd41a) sprintf(RealModelName, "SCPH-50008 SS"); // 40: 27204081 + else if (ModelId == 0xd41b) sprintf(RealModelName, "SCPH-50004 AQ"); // 51: 27205151 + else if (ModelId == 0xd41c) sprintf(RealModelName, "SCPH-50005 SS/N"); // 55: 27205525 + else if (ModelId == 0xd41d) sprintf(RealModelName, "SCPH-50005 AQ/N"); // 56: 27205625 + else if (ModelId == 0xd41e) sprintf(RealModelName, "SCPH-50000 CW"); // 44: 27204402 + else if (ModelId == 0xd41f) sprintf(RealModelName, "SCPH-50000 SA"); // 61: 27206101 + else if (ModelId == 0xd420) sprintf(RealModelName, "SCPH-50004 ESS"); // 57, 62, 66: 27205751, 27206251, 27206651 Satin Silver + /* else if (ModelId == 0xd421) sprintf(RealModelName, "???"); */ + else if (ModelId == 0xd422) sprintf(RealModelName, "SCPH-50002 ESS"); // 62: 27206291 Satin Silver + else if (ModelId == 0xd423) sprintf(RealModelName, "SCPH-50003 ESS"); // 66: 27206661 Satin Silver + else if (ModelId == 0xd424) sprintf(RealModelName, "SCPH-50000 PW"); // 65: 27206501 + else if (ModelId == 0xd425) sprintf(RealModelName, "SCPH-50011"); // ??: SM1 + // K-chassis + else if (ModelId == 0xd426) sprintf(RealModelName, "SCPH-70004"); + else if (ModelId == 0xd427) sprintf(RealModelName, "SCPH-70003"); + else if (ModelId == 0xd428) sprintf(RealModelName, "SCPH-70002"); + else if (ModelId == 0xd429) sprintf(RealModelName, "SCPH-70011"); + else if (ModelId == 0xd42a) sprintf(RealModelName, "SCPH-70012"); + else if (ModelId == 0xd42b) sprintf(RealModelName, "SCPH-70000"); + else if (ModelId == 0xd42c) sprintf(RealModelName, "SCPH-70005"); + else if (ModelId == 0xd42d) sprintf(RealModelName, "SCPH-70006"); + else if (ModelId == 0xd42e) sprintf(RealModelName, "SCPH-70007"); + else if (ModelId == 0xd42f) sprintf(RealModelName, "SCPH-70000 GT"); + else if (ModelId == 0xd430) sprintf(RealModelName, "SCPH-70008"); + else if (ModelId == 0xd431) sprintf(RealModelName, "SCPH-70002 SS"); + else if (ModelId == 0xd432) sprintf(RealModelName, "SCPH-70003 SS"); + else if (ModelId == 0xd433) sprintf(RealModelName, "SCPH-70004 SS"); + else if (ModelId == 0xd434) sprintf(RealModelName, "SCPH-70008 SS"); + else if (ModelId == 0xd435) sprintf(RealModelName, "SCPH-70001"); + else if (ModelId == 0xd436) sprintf(RealModelName, "SCPH-70010"); + else if (ModelId == 0xd437) sprintf(RealModelName, "SCPH-70000 CW"); + else if (ModelId == 0xd438) sprintf(RealModelName, "SCPH-70003 SS"); + else if (ModelId == 0xd439) sprintf(RealModelName, "SCPH-70004 SS"); + else if (ModelId == 0xd43a) sprintf(RealModelName, "SCPH-70008 SS"); + // L-chassis + else if (ModelId == 0xd43b) sprintf(RealModelName, "SCPH-75001"); + else if (ModelId == 0xd43c) sprintf(RealModelName, "SCPH-75002"); + else if (ModelId == 0xd43d) sprintf(RealModelName, "SCPH-75003"); + else if (ModelId == 0xd43e) sprintf(RealModelName, "SCPH-75004"); + else if (ModelId == 0xd43f) sprintf(RealModelName, "SCPH-75000 SSS"); + else if (ModelId == 0xd440) sprintf(RealModelName, "SCPH-75002 SS"); + else if (ModelId == 0xd441) sprintf(RealModelName, "SCPH-75003 SS"); + else if (ModelId == 0xd442) sprintf(RealModelName, "SCPH-75004 SS"); + else if (ModelId == 0xd443) sprintf(RealModelName, "SCPH-75000"); + else if (ModelId == 0xd444) sprintf(RealModelName, "SCPH-75000 CW"); + else if (ModelId == 0xd445) sprintf(RealModelName, "SCPH-75006"); + else if (ModelId == 0xd446) sprintf(RealModelName, "SCPH-75007"); + else if (ModelId == 0xd447) sprintf(RealModelName, "SCPH-75005"); + else if (ModelId == 0xd448) sprintf(RealModelName, "SCPH-75010"); + else if (ModelId == 0xd449) sprintf(RealModelName, "SCPH-75000 FF"); + /* else if (ModelId == 0xd44a) sprintf(RealModelName, "???"); + else if (ModelId == 0xd44b) sprintf(RealModelName, "???"); */ + else if (ModelId == 0xd44c) sprintf(RealModelName, "SCPH-75008"); + else if (ModelId == 0xd44d) sprintf(RealModelName, "SCPH-75008 SS"); + // M-chassis + else if (ModelId == 0xd44e) sprintf(RealModelName, "SCPH-77001"); + else if (ModelId == 0xd44f) sprintf(RealModelName, "SCPH-77002"); + else if (ModelId == 0xd450) sprintf(RealModelName, "SCPH-77003"); + else if (ModelId == 0xd451) sprintf(RealModelName, "SCPH-77004"); + else if (ModelId == 0xd452) sprintf(RealModelName, "SCPH-77002 SS"); + else if (ModelId == 0xd453) sprintf(RealModelName, "SCPH-77003 SS"); + else if (ModelId == 0xd454) sprintf(RealModelName, "SCPH-77004 SS"); + else if (ModelId == 0xd455) sprintf(RealModelName, "SCPH-77000"); + else if (ModelId == 0xd456) sprintf(RealModelName, "SCPH-77000 CW"); + else if (ModelId == 0xd457) sprintf(RealModelName, "SCPH-77005"); + else if (ModelId == 0xd458) sprintf(RealModelName, "SCPH-77006"); + else if (ModelId == 0xd459) sprintf(RealModelName, "SCPH-77007"); + else if (ModelId == 0xd45a) sprintf(RealModelName, "SCPH-77008"); + /* else if (ModelId == 0xd45b) sprintf(RealModelName, "??? SCPH-77010"); + else if (ModelId == 0xd45c) sprintf(RealModelName, "??? SCPH-77010 SS"); */ + else if (ModelId == 0xd45d) sprintf(RealModelName, "SCPH-77001 SS"); + else if (ModelId == 0xd45e) sprintf(RealModelName, "SCPH-77003 PK"); + else if (ModelId == 0xd45f) sprintf(RealModelName, "SCPH-77004 PK"); + /* else if (ModelId == 0xd460) sprintf(RealModelName, "??? SCPH-77008 SS"); */ + else if (ModelId == 0xd461) sprintf(RealModelName, "SCPH-77000 SS"); + else if (ModelId == 0xd462) sprintf(RealModelName, "SCPH-77000 PK"); + else if (ModelId == 0xd463) sprintf(RealModelName, "SCPH-77008 PK"); + else if (ModelId == 0xd464) sprintf(RealModelName, "SCPH-77002 PK"); + // N-chassis + else if (ModelId == 0xd465) sprintf(RealModelName, "SCPH-79001"); + /* else if (ModelId == 0xd466) sprintf(RealModelName, "??? SCPH-79000"); */ + else if (ModelId == 0xd467) sprintf(RealModelName, "SCPH-79000 CW"); + else if (ModelId == 0xd468) sprintf(RealModelName, "SCPH-79002"); + else if (ModelId == 0xd469) sprintf(RealModelName, "SCPH-79001 SS"); + /* else if (ModelId == 0xd46a) sprintf(RealModelName, "??? SCPH-79005"); */ + else if (ModelId == 0xd46b) sprintf(RealModelName, "SCPH-79006"); + /* else if (ModelId == 0xd46c) sprintf(RealModelName, "??? SCPH-79007"); */ + else if (ModelId == 0xd46d) sprintf(RealModelName, "SCPH-79000 SS"); + else if (ModelId == 0xd46e) sprintf(RealModelName, "SCPH-79003"); + else if (ModelId == 0xd46f) sprintf(RealModelName, "SCPH-79004"); + else if (ModelId == 0xd470) sprintf(RealModelName, "SCPH-79010"); + else if (ModelId == 0xd471) sprintf(RealModelName, "SCPH-79003 SS"); + /* else if (ModelId == 0xd472) sprintf(RealModelName, "??? SCPH-79004 SS"); */ + else if (ModelId == 0xd473) sprintf(RealModelName, "SCPH-79008"); + else if (ModelId == 0xd474) sprintf(RealModelName, "SCPH-79001 CW"); + // P/R-chassis + else if (ModelId == 0xd475) sprintf(RealModelName, "SCPH-90000"); + else if (ModelId == 0xd476) sprintf(RealModelName, "SCPH-90000 CW"); + else if (ModelId == 0xd477) sprintf(RealModelName, "SCPH-90000 SS"); + else if (ModelId == 0xd478) sprintf(RealModelName, "SCPH-90006"); + else if (ModelId == 0xd479) sprintf(RealModelName, "SCPH-90006 CW"); + else if (ModelId == 0xd47a) sprintf(RealModelName, "SCPH-90006 SS"); // Needs confirmation + else if (ModelId == 0xd47b) sprintf(RealModelName, "SCPH-90005"); + /* else if (ModelId == 0xd47c) sprintf(RealModelName, "??? SCPH-90005 CW"); + else if (ModelId == 0xd47d) sprintf(RealModelName, "??? SCPH-90005 SS"); */ + else if (ModelId == 0xd47e) sprintf(RealModelName, "SCPH-90007"); + else if (ModelId == 0xd47f) sprintf(RealModelName, "SCPH-90007 CW"); + /* else if (ModelId == 0xd480) sprintf(RealModelName, "??? SCPH-90007 SS"); */ + else if (ModelId == 0xd481) sprintf(RealModelName, "SCPH-90001"); + else if (ModelId == 0xd482) sprintf(RealModelName, "SCPH-90001 SS"); + else if (ModelId == 0xd483) sprintf(RealModelName, "SCPH-90004"); + else if (ModelId == 0xd484) sprintf(RealModelName, "SCPH-90004 SS"); + else if (ModelId == 0xd485) sprintf(RealModelName, "SCPH-90002"); + else if (ModelId == 0xd486) sprintf(RealModelName, "SCPH-90003"); + /* else if (ModelId == 0xd487) sprintf(RealModelName, "??? SCPH-90005 CR"); */ + else if (ModelId == 0xd488) sprintf(RealModelName, "SCPH-90006 CR"); + else if (ModelId == 0xd489) sprintf(RealModelName, "SCPH-90007 CR"); + else if (ModelId == 0xd48a) sprintf(RealModelName, "SCPH-90010"); + else if (ModelId == 0xd48b) sprintf(RealModelName, "SCPH-90000 CR"); + else if (ModelId == 0xd48c) sprintf(RealModelName, "SCPH-90008"); + else if (ModelId == 0xd48d) sprintf(RealModelName, "SCPH-90008 SS"); + /* else if (ModelId == 0xd48e) sprintf(RealModelName, "???"); */ + else if (ModelId == 0xd48f) sprintf(RealModelName, "PX300-1"); + else if (ModelId == 0xd490) sprintf(RealModelName, "PX300-2"); + else if (ModelId == 0xd491) sprintf(RealModelName, "SCPH-90010 CR"); + // clang-format on + else + { + errorTextures = ui_printf(8, 8 + big_size + big_size / 2 + 5 * (reg_size + 4), reg_size, 0xFFFFFF, "Model ID unknown, please report!\n"); + IsKnownconsole = 0; + } + modelnameTextures = ui_printf(8, 8 + big_size + big_size / 2 + 2 * (reg_size + 4), reg_size, 0xFFFFFF, "Real Model Name: %s\n", RealModelName); + + sprintf(color, "Black"); + if ((ModelId >= 0xd380 && ModelId <= 0xd388 && ModelId != 0xd384) || + (ModelId == 0xd414) || (ModelId == 0xd418) || (ModelId == 0xd41e) || /* (ModelId == 0xd419) || */ + (ModelId == 0xd424) || (ModelId == 0xd437) || (ModelId == 0xd444) || + (ModelId == 0xd456) || (ModelId == 0xd474) || (ModelId == 0xd476) || /* (ModelId == 0xd47c) || */ + (ModelId == 0xd479) || (ModelId == 0xd47f)) + sprintf(color, "White"); + else if ((ModelId == 0xd408) || (ModelId == 0xd409) || (ModelId == 0xd40a) || + (ModelId == 0xd412) || (ModelId == 0xd415) || (ModelId == 0xd41a) || /* (ModelId == 0xd417) || */ + (ModelId == 0xd41c) || (ModelId == 0xd420) || (ModelId == 0xd422) || /* (ModelId == 0xd421) || */ + (ModelId == 0xd423) || (ModelId == 0xd431) || (ModelId == 0xd432) || + (ModelId == 0xd433) || (ModelId == 0xd434) || (ModelId == 0xd437) || + (ModelId == 0xd438) || (ModelId == 0xd439) || (ModelId == 0xd43a) || + (ModelId == 0xd43f) || (ModelId == 0xd440) || (ModelId == 0xd441) || /* (ModelId == 0xd44a) || (ModelId == 0xd44b) || */ + (ModelId == 0xd442) || (ModelId == 0xd44d) || (ModelId == 0xd452) || + (ModelId == 0xd453) || (ModelId == 0xd454) || (ModelId == 0xd45d) || /* (ModelId == 0xd45c) || */ + (ModelId == 0xd461) || (ModelId == 0xd469) || (ModelId == 0xd46d) || /* (ModelId == 0xd460) || */ + (ModelId == 0xd471) || (ModelId == 0xd477) || (ModelId == 0xd47a) || /* (ModelId == 0xd472) || */ + (ModelId == 0xd482) || (ModelId == 0xd484) || (ModelId == 0xd48d) || /* (ModelId == 0xd47d) || (ModelId == 0xd480) || */ + (ModelId == 0xd384) || (ModelId == 0xd304) || (ModelId == 0xd22a)) + sprintf(color, "Satin Silver"); + else if ((ModelId == 0xd41f) || (ModelId == 0xd45e) || (ModelId == 0xd45f) || + (ModelId == 0xd462) || (ModelId == 0xd464) || (ModelId == 0xd22c)) + sprintf(color, "Pink"); + else if ((ModelId == 0xd404) || (ModelId == 0xd41b) || (ModelId == 0xd41d) || + (ModelId == 0xd21d) || (ModelId == 0xd220) || (ModelId == 0xd22b) || + (ModelId == 0xd463)) + sprintf(color, "Blue"); + else if ((ModelId == 0xd488) || (ModelId == 0xd489) || (ModelId == 0xd48b) || /* (ModelId == 0xd487) || */ + (ModelId == 0xd491)) + sprintf(color, "Cinnabar Red"); + else if (ModelId == 0xd413) + sprintf(color, "Gold"); + + colorTextures = ui_printf(8, 8 + big_size + big_size / 2 + 3 * (reg_size + 4), reg_size, 0xFFFFFF, "Console color: %s\n", color); + + if (getMechaBuildDate(build_date)) + { + buildTextures = ui_printf(8, 8 + big_size + big_size / 2 + 1 * (reg_size + 4), reg_size, 0xFFFFFF, "Mecha build date: 20%02x/%02x/%02x %02x:%02x\n", build_date[0], build_date[1], build_date[2], build_date[3], build_date[4]); + + if (!getPatch(build_date)) + { + errorTextures = draw_text(8, 8 + big_size + big_size / 2 + 5 * (reg_size + 4), reg_size, 0xFFFFFF, "MechaCon unknown, please report!\n"); + + drawFrame(); + + if (!(IsKnownconsole)) + freeGSTEXTURE_holder(errorTextures); + freeGSTEXTURE_holder(romverTextures); + freeGSTEXTURE_holder(colorTextures); + freeGSTEXTURE_holder(modelnameTextures); + freeGSTEXTURE_holder(ModelIDTextures); + freeGSTEXTURE_holder(serialTextures); + if (getMechaBuildDate(build_date)) + freeGSTEXTURE_holder(buildTextures); + freeGSTEXTURE_holder(versionTextures); + freeGSTEXTURE_holder(errorTextures); + + SleepThread(); + return; + } + } + + if ((ModelId >= 0xd300) && (ModelId < 0xd380)) + { + errorTextures = draw_text(8, 8 + big_size + big_size / 2 + 5 * (reg_size + 4), reg_size, 0xFFFFFF, "Dragon TEST support is blocked!\n"); + IsKnownconsole = 0; + } + + // todo: fixme: find out why isPatchKnown is crashing + /* if (!isPatchKnown()) + { + uint8_t current_patch[224]; + + for (int i = 0; i < 112; i++) + { + if (!ReadNVM(400 + i, (uint16_t *)¤t_patch[i * 2])) + break; + } + warnTextures1 = draw_text(8, 8 + big_size + big_size / 2 + 5 * (reg_size + 4), reg_size, 0xFFFFFF, "Unknown patch, please report!\n"); + warnTextures2 = ui_printf(8, 8 + big_size + big_size / 2 + 6 * (reg_size + 4), reg_size, 0xFFFFFF, " %02X %02X %02X %02X %02X\n", current_patch[0], current_patch[1], current_patch[2], current_patch[3], current_patch[4]); + } + else + { + warnTextures1 = draw_text(8, 8 + big_size + big_size / 2 + 5 * (reg_size + 4), reg_size, 0xFFFFFF, "\n"); + warnTextures2 = draw_text(8, 8 + big_size + big_size / 2 + 6 * (reg_size + 4), reg_size, 0xFFFFFF, "\n"); + } */ + + + struct GSTEXTURE_holder *exitTextures = draw_text(8, 8 + big_size + big_size / 2 + 7 * (reg_size + 4), reg_size, 0xFFFFFF, "Press X to continue.\n"); + drawFrame(); + + if (!(IsKnownconsole)) + freeGSTEXTURE_holder(errorTextures); + freeGSTEXTURE_holder(exitTextures); + freeGSTEXTURE_holder(colorTextures); + freeGSTEXTURE_holder(modelnameTextures); + freeGSTEXTURE_holder(ModelIDTextures); + freeGSTEXTURE_holder(serialTextures); + if (getMechaBuildDate(build_date)) + freeGSTEXTURE_holder(buildTextures); + freeGSTEXTURE_holder(versionTextures); + freeGSTEXTURE_holder(romverTextures); + // freeGSTEXTURE_holder(warnTextures2); + // freeGSTEXTURE_holder(warnTextures1); + + while (1) + { + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_CROSS) + break; + } +} + +char isPatchAlreadyInstalled() +{ + uint8_t build_date[5]; + getMechaBuildDate(build_date); + + uint8_t current_patch[224]; + + for (int i = 0; i < 112; i++) + { + if (!ReadNVM(400 + i, (uint16_t *)¤t_patch[i * 2])) + break; + } + + const uint8_t *patch = getPatch(build_date); + + return memcmp(current_patch, patch, 224) == 0; +} + +char restoreBackup() +{ + uint32_t serial[1]; + getSerial(serial); + uint8_t version[4]; + getMechaVersion(version); + + char nvm_path[256]; + sprintf(nvm_path, "mass:/nvm_%d.%02d_%07ld.bin", version[1], (version[2] | 1) - 1, serial[0]); + + FILE *f = fopen(nvm_path, "rb"); + if (!f) + { + gsKit_clear(gsGlobal, Black); + char text[] = "Failed to open NVRAM backup!"; + + int x, y; + getTextSize(reg_size, text, &x, &y); + y += reg_size; + + struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, text); + struct GSTEXTURE_holder *exitTextures = draw_text(8, 8 + big_size + big_size / 2 + 6 * (reg_size + 4), reg_size, 0xFFFFFF, "Press X to exit.\n"); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + freeGSTEXTURE_holder(exitTextures); + while (1) + { + u32 new_pad = ReadCombinedPadStatus(); + + if (new_pad & PAD_CROSS) + { + ResetIOP(); + Exit(0); + SleepThread(); + } + } + return 0; + } + else + { + fseek(f, 0, SEEK_END); + int len = ftell(f); + fclose(f); + if (len != 1024) + { + gsKit_clear(gsGlobal, Black); + char text[] = "Failed to open NVRAM backup!"; + + int x, y; + getTextSize(reg_size, text, &x, &y); + y += reg_size; + + struct GSTEXTURE_holder *textTextures = draw_text((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, text); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + return 0; + } + } + + int x, y; + getTextSize(reg_size, "Restoring NVRAM backup...", &x, &y); + y += reg_size; + + gsKit_clear(gsGlobal, Black); + struct GSTEXTURE_holder *textTextures = ui_printf((gsGlobal->Width - x) / 2, (gsGlobal->Height - y) / 2, reg_size, 0xFFFFFF, "Restoring NVRAM backup..."); + drawFrame(); + freeGSTEXTURE_holder(textTextures); + + f = fopen(nvm_path, "rb"); + for (int i = 0; i < 0x200; i++) + { + uint16_t data; + fread(&data, 1, 2, f); + if (!WriteNVM(i, data)) + break; + } + + fclose(f); + return 1; +} + +int main() +{ + init_ui(); + + gsKit_mode_switch(gsGlobal, GS_ONESHOT); + + gsKit_clear(gsGlobal, Black); + + struct GSTEXTURE_holder *loadingTextures = draw_text(-8, -reg_size - 8, reg_size, 0xFFFFFF, "Loading..."); + drawFrame(); + freeGSTEXTURE_holder(loadingTextures); + + ResetIOP(); + + sbv_patch_enable_lmb(); + sbv_patch_disable_prefix_check(); + sbv_patch_fileio(); + + SifExecModuleBuffer(&iomanX, size_iomanX, 0, NULL, NULL); + SifExecModuleBuffer(&fileXio, size_fileXio, 0, NULL, NULL); + SifExecModuleBuffer(&freesio2, size_freesio2, 0, NULL, NULL); + SifExecModuleBuffer(&freepad, size_freepad, 0, NULL, NULL); + SifExecModuleBuffer(&mcman, size_mcman, 0, NULL, NULL); + SifExecModuleBuffer(&mcserv, size_mcserv, 0, NULL, NULL); + SifExecModuleBuffer(&USBD, size_USBD, 0, NULL, NULL); + SifExecModuleBuffer(&USBHDFSD, size_USBHDFSD, 0, NULL, NULL); + SifExecModuleBuffer(&MECHAPROXY_irx, size_MECHAPROXY_irx, 0, NULL, NULL); + SifExecModuleBuffer(&MASSWATCHER_irx, size_MASSWATCHER_irx, 0, NULL, NULL); + + MechaInit(); + MassInit(); + + // TODO: do we need this? + // mcInit(MC_TYPE_XMC); + + PadInitPads(); + + // --- + + drawLogo(); + + backupNVM(); + checkUnsupportedVersion(); + checkFMCB(); + + uint8_t *powerTexture = getPowerTexture(); + + char rerun = 0; + int selected = 0; + if (!IsNVMUnlocked()) + { + rerun = 1; + unlockNVM(); + } + else + { + uint8_t build_date[5]; + gsKit_clear(gsGlobal, Black); + + struct MENU menu; + menu.title = "MechaPwn"; + menu.x_text = "X Select"; + menu.o_text = "O Exit"; + + + menu.option_count = 2; + if (getMechaBuildDate(build_date) && IsKnownconsole) + menu.options[0] = "Change region"; + else + menu.options[0] = "Exit"; + menu.options[1] = "Restore NVRAM backup"; + + selected = drawMenu(&menu); + + if (selected == -1) + { + ResetIOP(); + Exit(0); + SleepThread(); + } + else if (selected == 0) + { + if (getMechaBuildDate(build_date) && IsKnownconsole) + { + char isDex = 0; + setRegion(&isDex); + applyPatches(isDex); + } + else + { + ResetIOP(); + Exit(0); + SleepThread(); + } + } + else if (selected == 1) + { + restoreBackup(); + } + } + + gsKit_clear(gsGlobal, Black); + MassDeinit(); + + struct GSTEXTURE_holder *imageTextures = drawImage((gsGlobal->Width - 400) / 2, (gsGlobal->Height - (225 + 60)) / 2, 400, 225, powerTexture); + + const char *text1 = "Unplug the power cord."; + int x1, y1; + getTextSize(reg_size, text1, &x1, &y1); + y1 += reg_size; + struct GSTEXTURE_holder *unplugTextures = draw_text((gsGlobal->Width - x1) / 2, ((gsGlobal->Height - (225 + 60)) / 2) + 225, reg_size, 0xFFFFFF, text1); + + struct GSTEXTURE_holder *rerunTextures = 0; + + const char *text2; + int x2, y2; + if (rerun) + text2 = "Run MechaPwn again."; + else if (selected == 1) + text2 = "Backup restored successfuly."; + else + text2 = "Installation complete! Enjoy MechaPwn"; + + getTextSize(reg_size, text2, &x2, &y2); + y2 += reg_size; + rerunTextures = draw_text((gsGlobal->Width - x2) / 2, ((gsGlobal->Height - (195)) / 2) + 225, reg_size, 0xFFFFFF, text2); + + drawFrame(); + if (rerunTextures) + freeGSTEXTURE_holder(rerunTextures); + freeGSTEXTURE_holder(unplugTextures); + freeGSTEXTURE_holder(imageTextures); + + + // --- + + SleepThread(); + + return 0; +} diff --git a/mass.c b/mass.c index ff1036a..ff97423 100644 --- a/mass.c +++ b/mass.c @@ -18,6 +18,8 @@ #include #include #include +#define NEWLIB_PORT_AWARE +#include // fileXioDevctl #include "mass.h" #include "masswatcher.h" @@ -30,31 +32,33 @@ static unsigned char RpcBuffer[0x1000] ALIGNED(64); int MassInit() { - SifInitRpc(0); + SifInitRpc(0); - nopdelay(); - while(SifBindRpc(&SifRpcClientMass, MASSWATCHER_HEADER, 0) < 0 || SifRpcClientMass.server == NULL) - { - _printf("libsecr: bind failed\n"); - } + nopdelay(); + while (SifBindRpc(&SifRpcClientMass, MASSWATCHER_HEADER, 0) < 0 || SifRpcClientMass.server == NULL) + { + _printf("libsecr: bind failed\n"); + } - return 1; + return 1; } void MassDeinit() { - memset(&SifRpcClientMass, 0, sizeof(SifRpcClientData_t)); + memset(&SifRpcClientMass, 0, sizeof(SifRpcClientData_t)); + // As required by some (typically 2.5") HDDs, issue the SCSI STOP UNIT command to avoid causing an emergency park. + fileXioDevctl("mass:", 0x0001, NULL, 0, NULL, 0); } char MassCheck() { - char *params = (char *) RpcBuffer; + char *params = (char *)RpcBuffer; - if(SifCallRpc(&SifRpcClientMass, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) - { - _printf("MassScmd: rpc error\n"); - return 0; - } + if (SifCallRpc(&SifRpcClientMass, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) + { + _printf("MassScmd: rpc error\n"); + return 0; + } - return *params; + return *params; } diff --git a/mecha.c b/mecha.c index 5302639..eb516ae 100644 --- a/mecha.c +++ b/mecha.c @@ -27,203 +27,227 @@ static SifRpcClientData_t SifRpcClientMechaScmd; static unsigned char RpcBuffer[0x1000] ALIGNED(64); -#define _printf(args...) //scr_printf(args) +#define _printf(args...) // scr_printf(args) int MechaInit() { - SifInitRpc(0); + SifInitRpc(0); - nopdelay(); - while(SifBindRpc(&SifRpcClientMechaScmd, MECHAPROXY_SCMD_HEADER, 0) < 0 || SifRpcClientMechaScmd.server == NULL) - { - _printf("libsecr: bind failed\n"); - } + nopdelay(); + while (SifBindRpc(&SifRpcClientMechaScmd, MECHAPROXY_SCMD_HEADER, 0) < 0 || SifRpcClientMechaScmd.server == NULL) + { + _printf("libsecr: bind failed\n"); + } - return 1; + return 1; } void MechaDeinit() { - memset(&SifRpcClientMechaScmd, 0, sizeof(SifRpcClientData_t)); + memset(&SifRpcClientMechaScmd, 0, sizeof(SifRpcClientData_t)); } int MechaScmd(u8 cmd, void *input, u8 inputlength, void *output) { - struct MechaScmdParams *params = (struct MechaScmdParams *) RpcBuffer; + struct MechaScmdParams *params = (struct MechaScmdParams *)RpcBuffer; - params->cmd = cmd; - params->inputlength = inputlength; - memcpy(params->input, input, inputlength); + params->cmd = cmd; + params->inputlength = inputlength; + memcpy(params->input, input, inputlength); - if(SifCallRpc(&SifRpcClientMechaScmd, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) - { - _printf("MechaScmd: rpc error\n"); - return 0; - } + if (SifCallRpc(&SifRpcClientMechaScmd, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) + { + _printf("MechaScmd: rpc error\n"); + return 0; + } - memcpy(output, params->output, 16); + memcpy(output, params->output, 16); - return params->result; + return params->result; } - - char getMechaVersion(uint8_t *data) { - u8 input[1]; - u8 output[16]; - input[0] = 0x00; - if (MechaScmd(0x03, input, sizeof(input), output) != 1) - { - return 0; - } - - memcpy(data, &output[0], 3); - - return 1; + u8 input[1]; + u8 output[16]; + input[0] = 0x00; + + if (MechaScmd(0x03, input, sizeof(input), output) != 1) + { + return 0; + } + + memcpy(data, &output[0], 4); + + return 1; } char getMechaBuildDate(uint8_t *data) { - u8 input[1]; - u8 output[16]; - input[0] = 0xfd; - if (MechaScmd(0x03, input, sizeof(input), output) != 1 || output[0] != 0) - { - _printf("Failed to read the build date!\n"); - return 0; - } - - memcpy(data, &output[1], 5); - - return 1; + u8 input[1]; + u8 output[16]; + input[0] = 0xfd; + if (MechaScmd(0x03, input, sizeof(input), output) != 1 || output[0] != 0) + { + _printf("Failed to read the build date!\n"); + return 0; + } + + memcpy(data, &output[1], 5); + + return 1; } char OpenConfig(uint8_t id, char write, uint8_t blocks) { - u8 input[3]; - u8 output[16]; - - input[0] = write; // 0 = read, 1 = write - input[1] = id; // id - input[2] = blocks; // blocks - - if (MechaScmd(0x40, input, sizeof(input), output) != 1) - { - if (output[0] != 0) - { - CloseConfig(); - - if (MechaScmd(0x40, input, sizeof(input), output) != 1 || output[0] != 0) - { - _printf("Failed to cmd OpenConfig!\n"); - return 0; - } - } - } - - return 1; + u8 input[3]; + u8 output[16]; + + input[0] = write; // 0 = read, 1 = write + input[1] = id; // id + input[2] = blocks; // blocks + + if (MechaScmd(0x40, input, sizeof(input), output) != 1) + { + if (output[0] != 0) + { + CloseConfig(); + + if (MechaScmd(0x40, input, sizeof(input), output) != 1 || output[0] != 0) + { + _printf("Failed to cmd OpenConfig!\n"); + return 0; + } + } + } + + return 1; } char ReadConfig(uint8_t *data) { - u8 input[0]; - u8 output[16]; - - if (MechaScmd(0x41, input, sizeof(input), output) != 1) - { - _printf("Failed to cmd ReadConfig!\n"); - return 0; - } - - memcpy(data, output, 16); - - return 1; + u8 input[0]; + u8 output[16]; + + if (MechaScmd(0x41, input, sizeof(input), output) != 1) + { + _printf("Failed to cmd ReadConfig!\n"); + return 0; + } + + memcpy(data, output, 16); + + return 1; } char WriteConfig(const uint8_t *data) { - u8 input[16]; - u8 output[16]; - - memcpy(input, data, 16); - - if (MechaScmd(0x42, input, sizeof(input), output) != 1 || output[0] != 0) - { - _printf("Failed to cmd WriteConfig!\n"); - return 0; - } - - return 1; + u8 input[16]; + u8 output[16]; + + memcpy(input, data, 16); + + if (MechaScmd(0x42, input, sizeof(input), output) != 1 || output[0] != 0) + { + _printf("Failed to cmd WriteConfig!\n"); + return 0; + } + + return 1; } char CloseConfig() { - u8 input[0]; - u8 output[16]; - output[0] = 1; - - while (output[0]) - { - if (MechaScmd(0x43, input, sizeof(input), output) != 1 || (output[0] != 0 && output[0] != 1)) - { - _printf("Failed to cmd CloseConfig!\n"); - return 0; - } - } - - return 1; + u8 input[0]; + u8 output[16]; + output[0] = 1; + + while (output[0]) + { + if (MechaScmd(0x43, input, sizeof(input), output) != 1 || (output[0] != 0 && output[0] != 1)) + { + _printf("Failed to cmd CloseConfig!\n"); + return 0; + } + } + + return 1; } char ReadNVM(uint16_t offset, uint16_t *data) { - u8 input[2]; - u8 output[16]; - input[0] = offset >> 8; - input[1] = offset; - if (MechaScmd(0x0A, input, sizeof(input), output) != 1 || output[0] != 0) - { - _printf("Failed to cmd 0x0A!\n"); - return 0; - } - - *data = output[1]; - *data <<= 8; - *data |= output[2]; - - return 1; + u8 input[2]; + u8 output[16]; + input[0] = offset >> 8; + input[1] = offset; + if (MechaScmd(0x0A, input, sizeof(input), output) != 1 || output[0] != 0) + { + _printf("Failed to cmd 0x0A!\n"); + return 0; + } + + *data = output[1]; + *data <<= 8; + *data |= output[2]; + + return 1; } char WriteNVM(uint16_t offset, uint16_t data) { - u8 input[4]; - u8 output[16]; - input[0] = offset >> 8; - input[1] = offset; - input[2] = data >> 8; - input[3] = data; - output[0] = 1; - - while (output[0]) - { - if (MechaScmd(0x0B, input, sizeof(input), output) != 1 || (output[0] != 0 && output[0] != 1)) - { - _printf("Failed to cmd WriteNVM! (%d)\n", offset); - return 0; - } - } - - return 1; + u8 input[4]; + u8 output[16]; + input[0] = offset >> 8; + input[1] = offset; + input[2] = data >> 8; + input[3] = data; + output[0] = 1; + + while (output[0]) + { + if (MechaScmd(0x0B, input, sizeof(input), output) != 1 || (output[0] != 0 && output[0] != 1)) + { + _printf("Failed to cmd WriteNVM! (%d)\n", offset); + return 0; + } + } + + return 1; } char IsNVMUnlocked() { - uint16_t data; - if (!ReadNVM(400, &data)) - return 0; - - if (!WriteNVM(400, data)) - return 0; - - return 1; + uint16_t data; + if (!ReadNVM(400, &data)) + return 0; + + if (!WriteNVM(400, data)) + return 0; + + return 1; +} + +char getSerial(uint32_t *serial) +{ + uint16_t part1; + uint16_t part2; + uint8_t version[4]; + if (!ReadNVM(0xFA, &part1)) + return 0; + if (!ReadNVM(0xFB, &part2)) + return 0; + + if (getMechaVersion(version)) + { + if (version[1] < 4) + { + if (!ReadNVM(0xE6, &part1)) + return 0; + if (!ReadNVM(0xE7, &part2)) + return 0; + } + } + + *serial = ((part2 & 0xff) << 16) | part1; + return 1; } diff --git a/mecha.h b/mecha.h index 08d3432..4782374 100644 --- a/mecha.h +++ b/mecha.h @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +#include + int MechaInit(); void MechaDeinit(); char getMechaVersion(uint8_t *data); @@ -25,3 +27,4 @@ char CloseConfig(); char ReadNVM(uint16_t offset, uint16_t *data); char WriteNVM(uint16_t offset, uint16_t data); char IsNVMUnlocked(); +char getSerial(uint32_t *serial); diff --git a/resources/50k.png b/resources/50k.png deleted file mode 100644 index d4671f5..0000000 Binary files a/resources/50k.png and /dev/null differ diff --git a/resources/70k.png b/resources/70k.png deleted file mode 100644 index 000aab8..0000000 Binary files a/resources/70k.png and /dev/null differ diff --git a/resources/90k.png b/resources/90k.png deleted file mode 100644 index 23e4ce2..0000000 Binary files a/resources/90k.png and /dev/null differ diff --git a/resources/RLE24.py b/resources/RLE24.py index ed26229..0436450 100644 --- a/resources/RLE24.py +++ b/resources/RLE24.py @@ -17,117 +17,120 @@ from struct import pack, unpack from PIL import Image + def encode(line): - count = 0 - lst = [] - repeat = -1 - run = [] - total = len(line) - 1 - for index, current in enumerate(line[:-1]): - if current != line[index + 1]: - run.append(current) - count += 1 - if repeat == 1: - lst.append((count + 128, run)) - count = 0 - run = [] - repeat = -1 - if index == total - 1: - run = [line[index + 1]] - lst.append((1, run)) - else: - repeat = 0 + count = 0 + lst = [] + repeat = -1 + run = [] + total = len(line) - 1 + for index, current in enumerate(line[:-1]): + if current != line[index + 1]: + run.append(current) + count += 1 + if repeat == 1: + lst.append((count + 128, run)) + count = 0 + run = [] + repeat = -1 + if index == total - 1: + run = [line[index + 1]] + lst.append((1, run)) + else: + repeat = 0 + + if count == 128: + lst.append((128, run)) + count = 0 + run = [] + repeat = -1 + if index == total - 1: + run.append(line[index + 1]) + lst.append((count + 1, run)) + else: + if repeat == 0: + lst.append((count, run)) + count = 0 + run = [] + repeat = -1 + if index == total - 1: + run.append(line[index + 1]) + run.append(line[index + 1]) + lst.append((2 + 128, run)) + break + run.append(current) + repeat = 1 + count += 1 + if count == 128: + lst.append((256, run)) + count = 0 + run = [] + repeat = -1 + if index == total - 1: + if count == 0: + run = [line[index + 1]] + lst.append((1, run)) + else: + run.append(current) + lst.append((count + 1 + 128, run)) + return lst - if count == 128: - lst.append((128, run)) - count = 0 - run = [] - repeat = -1 - if index == total - 1: - run.append(line[index + 1]) - lst.append((count + 1, run)) - else: - if repeat == 0: - lst.append((count,run)) - count = 0 - run = [] - repeat = -1 - if index == total - 1: - run.append(line[index + 1]) - run.append(line[index + 1]) - lst.append((2 + 128, run)) - break - run.append(current) - repeat = 1 - count += 1 - if count == 128: - lst.append((256, run)) - count = 0 - run = [] - repeat = -1 - if index == total - 1: - if count == 0: - run = [line[index + 1]] - lst.append((1, run)) - else: - run.append(current) - lst.append((count + 1 + 128, run)) - return lst def encodeRLE24(img): - width, height = img.size - output = '' + width, height = img.size + output = b'' + + for h in range(height): + line = [] + result = [] + for w in range(width): + r, g, b = img.getpixel((w, h)) + line.append((r << 16) + (g << 8) + b) + result = encode(line) + for count, pixel in result: + output += pack("B", count - 1) + if count > 128: + output += pack("B", (pixel[0]) & 0xFF) + output += pack("B", ((pixel[0]) >> 8) & 0xFF) + output += pack("B", ((pixel[0]) >> 16) & 0xFF) + else: + for item in pixel: + output += pack("B", (item) & 0xFF) + output += pack("B", (item >> 8) & 0xFF) + output += pack("B", (item >> 16) & 0xFF) + return output - for h in range(height): - line = [] - result=[] - for w in range(width): - r, g, b = img.getpixel((w, h)) - line.append((r << 16) + (g << 8) + b) - result = encode(line) - for count, pixel in result: - output += pack("B", count - 1) - if count > 128: - output += pack("B", (pixel[0]) & 0xFF) - output += pack("B", ((pixel[0]) >> 8) & 0xFF) - output += pack("B", ((pixel[0]) >> 16) & 0xFF) - else: - for item in pixel: - output += pack("B", (item) & 0xFF) - output += pack("B", (item >> 8) & 0xFF) - output += pack("B", (item >> 16) & 0xFF) - return output def decodeRLE24(rle, size): - bgcolor = (0x00, 0x00, 0x00) - width, height = size - img = Image.new("RGB", size, bgcolor) - pixels = img.load() - pos = 0 - x = 0 - y = 0 - - hw = 0 - while hw < height * width: - count = unpack("B", rle[pos : pos + 1])[0] - pos += 1 - repeat_run = count & 0x80 - count = (count & 0x7f) + 1 - - for i in range(count): - b, g, r = unpack("BBB", rle[pos : pos + 3]) - pixels[x, y] = r, g, b - hw += 1 - x += 1 + bgcolor = (0x00, 0x00, 0x00) + width, height = size + img = Image.new("RGB", size, bgcolor) + pixels = img.load() + pos = 0 + x = 0 + y = 0 + + hw = 0 + while hw < height * width: + count = unpack("B", rle[pos: pos + 1])[0] + pos += 1 + repeat_run = count & 0x80 + count = (count & 0x7f) + 1 + + for i in range(count): + b, g, r = unpack("BBB", rle[pos: pos + 3]) + pixels[x, y] = r, g, b + hw += 1 + x += 1 + + if not repeat_run: + pos += 3 - if not repeat_run: - pos += 3 + if repeat_run: + pos += 3 - if repeat_run: - pos += 3 - - if x == width + 0: - y += 1 - x = 0 + if x == width + 0: + y += 1 + x = 0 - return img + return img diff --git a/resources/conv.py b/resources/conv.py index c5b578d..70ced18 100644 --- a/resources/conv.py +++ b/resources/conv.py @@ -14,28 +14,29 @@ # along with this program. If not, see . # -import sys, os +import sys +import os from PIL import Image -from RLE24 import encodeRLE24, decodeRLE24 +from RLE24 import encodeRLE24 img = Image.open(sys.argv[1]) bgcolor = (0x00, 0x00, 0x00, 0x00) if img.mode == "RGB" or img.mode == "P" or img.mode == "L": - background = Image.new("RGB", img.size, bgcolor) - img.load() - background.paste(img) + background = Image.new("RGB", img.size, bgcolor) + img.load() + background.paste(img) elif img.mode == "RGBA": - background = Image.new("RGB", img.size, bgcolor) - img.load() - background.paste(img, mask = img.split()[3]) # alpha channel + background = Image.new("RGB", img.size, bgcolor) + img.load() + background.paste(img, mask=img.split()[3]) # alpha channel else: - print ("sorry, can't support this format") - sys.exit() - -#r, g, b = background.split() -#data = Image.merge("RGB", (r, g, b)).tobytes() + print("sorry, can't support this format") + sys.exit() + +# r, g, b = background.split() +# data = Image.merge("RGB", (r, g, b)).tobytes() data = encodeRLE24(background) diff --git a/resources/frame_001.png b/resources/frame_001.png index bf5ffac..db43aa5 100644 Binary files a/resources/frame_001.png and b/resources/frame_001.png differ diff --git a/resources/frame_002.png b/resources/frame_002.png index da2b36a..9f6eb39 100644 Binary files a/resources/frame_002.png and b/resources/frame_002.png differ diff --git a/resources/frame_003.png b/resources/frame_003.png index 624fc30..3282225 100644 Binary files a/resources/frame_003.png and b/resources/frame_003.png differ diff --git a/resources/frame_004.png b/resources/frame_004.png index 59a53bd..f163a5e 100644 Binary files a/resources/frame_004.png and b/resources/frame_004.png differ diff --git a/resources/frame_005.png b/resources/frame_005.png index c1b5d36..609c1ba 100644 Binary files a/resources/frame_005.png and b/resources/frame_005.png differ diff --git a/resources/frame_006.png b/resources/frame_006.png index 04daab8..7f5dee1 100644 Binary files a/resources/frame_006.png and b/resources/frame_006.png differ diff --git a/resources/frame_007.png b/resources/frame_007.png index 1e0a8f8..1b21a0a 100644 Binary files a/resources/frame_007.png and b/resources/frame_007.png differ diff --git a/resources/frame_008.png b/resources/frame_008.png index 160e8b2..b6d89a9 100644 Binary files a/resources/frame_008.png and b/resources/frame_008.png differ diff --git a/resources/frame_009.png b/resources/frame_009.png index bd691ec..45cce33 100644 Binary files a/resources/frame_009.png and b/resources/frame_009.png differ diff --git a/resources/frame_010.png b/resources/frame_010.png index 40b879e..419277a 100644 Binary files a/resources/frame_010.png and b/resources/frame_010.png differ diff --git a/resources/frame_011.png b/resources/frame_011.png index 8087721..ebc9679 100644 Binary files a/resources/frame_011.png and b/resources/frame_011.png differ diff --git a/resources/frame_012.png b/resources/frame_012.png index c8a3382..27be2cf 100644 Binary files a/resources/frame_012.png and b/resources/frame_012.png differ diff --git a/resources/frame_013.png b/resources/frame_013.png index 2705646..b8f4218 100644 Binary files a/resources/frame_013.png and b/resources/frame_013.png differ diff --git a/resources/frame_014.png b/resources/frame_014.png index e08e50b..a668121 100644 Binary files a/resources/frame_014.png and b/resources/frame_014.png differ diff --git a/resources/frame_015.png b/resources/frame_015.png index c6edc90..1436af1 100644 Binary files a/resources/frame_015.png and b/resources/frame_015.png differ diff --git a/resources/frame_016.png b/resources/frame_016.png index 36929fd..ac03180 100644 Binary files a/resources/frame_016.png and b/resources/frame_016.png differ diff --git a/resources/frame_017.png b/resources/frame_017.png index 04ece18..cf9f4b6 100644 Binary files a/resources/frame_017.png and b/resources/frame_017.png differ diff --git a/resources/frame_018.png b/resources/frame_018.png index b3dab12..c37aebb 100644 Binary files a/resources/frame_018.png and b/resources/frame_018.png differ diff --git a/resources/frame_019.png b/resources/frame_019.png index f51d989..a604f0a 100644 Binary files a/resources/frame_019.png and b/resources/frame_019.png differ diff --git a/resources/frame_020.png b/resources/frame_020.png index ce45e6b..351f6dd 100644 Binary files a/resources/frame_020.png and b/resources/frame_020.png differ diff --git a/resources/frame_021.png b/resources/frame_021.png index ce8fa13..6999937 100644 Binary files a/resources/frame_021.png and b/resources/frame_021.png differ diff --git a/resources/frame_022.png b/resources/frame_022.png index 228463b..733bb04 100644 Binary files a/resources/frame_022.png and b/resources/frame_022.png differ diff --git a/resources/frame_023.png b/resources/frame_023.png index 322c353..852d239 100644 Binary files a/resources/frame_023.png and b/resources/frame_023.png differ diff --git a/resources/frame_024.png b/resources/frame_024.png index dafaed4..a4bac6b 100644 Binary files a/resources/frame_024.png and b/resources/frame_024.png differ diff --git a/resources/frame_025.png b/resources/frame_025.png index 4c9616b..502c165 100644 Binary files a/resources/frame_025.png and b/resources/frame_025.png differ diff --git a/resources/frame_026.png b/resources/frame_026.png index f797ad8..c2d9e64 100644 Binary files a/resources/frame_026.png and b/resources/frame_026.png differ diff --git a/resources/frame_027.png b/resources/frame_027.png index e931194..330128c 100644 Binary files a/resources/frame_027.png and b/resources/frame_027.png differ diff --git a/resources/frame_028.png b/resources/frame_028.png index 55e899f..e72ac99 100644 Binary files a/resources/frame_028.png and b/resources/frame_028.png differ diff --git a/resources/frame_029.png b/resources/frame_029.png index 9c69da0..569f421 100644 Binary files a/resources/frame_029.png and b/resources/frame_029.png differ diff --git a/resources/frame_030.png b/resources/frame_030.png index a3701ee..2a1b674 100644 Binary files a/resources/frame_030.png and b/resources/frame_030.png differ diff --git a/resources/frame_031.png b/resources/frame_031.png index a97a74d..6fc680b 100644 Binary files a/resources/frame_031.png and b/resources/frame_031.png differ diff --git a/resources/frame_032.png b/resources/frame_032.png index 9228316..0f9729f 100644 Binary files a/resources/frame_032.png and b/resources/frame_032.png differ diff --git a/resources/frame_033.png b/resources/frame_033.png index d8486b0..c3e0006 100644 Binary files a/resources/frame_033.png and b/resources/frame_033.png differ diff --git a/resources/frame_034.png b/resources/frame_034.png index 7ba3689..49c0e61 100644 Binary files a/resources/frame_034.png and b/resources/frame_034.png differ diff --git a/resources/frame_035.png b/resources/frame_035.png index 0fa10dd..b20e546 100644 Binary files a/resources/frame_035.png and b/resources/frame_035.png differ diff --git a/resources/frame_036.png b/resources/frame_036.png index ef7385b..aaf3ac3 100644 Binary files a/resources/frame_036.png and b/resources/frame_036.png differ diff --git a/resources/frame_037.png b/resources/frame_037.png index 8f2e34a..cfbac64 100644 Binary files a/resources/frame_037.png and b/resources/frame_037.png differ diff --git a/resources/frame_038.png b/resources/frame_038.png index c3ca2b8..ec61840 100644 Binary files a/resources/frame_038.png and b/resources/frame_038.png differ diff --git a/resources/frame_039.png b/resources/frame_039.png index 13bd5a1..ec9c963 100644 Binary files a/resources/frame_039.png and b/resources/frame_039.png differ diff --git a/resources/frame_040.png b/resources/frame_040.png index 409db79..b938826 100644 Binary files a/resources/frame_040.png and b/resources/frame_040.png differ diff --git a/resources/frame_041.png b/resources/frame_041.png index dda43e8..0244c4c 100644 Binary files a/resources/frame_041.png and b/resources/frame_041.png differ diff --git a/resources/frame_042.png b/resources/frame_042.png index 09639d7..0bbe6dd 100644 Binary files a/resources/frame_042.png and b/resources/frame_042.png differ diff --git a/resources/frame_043.png b/resources/frame_043.png index c94fca9..2bfc6bd 100644 Binary files a/resources/frame_043.png and b/resources/frame_043.png differ diff --git a/resources/frame_044.png b/resources/frame_044.png index c94ae0d..1a1ea59 100644 Binary files a/resources/frame_044.png and b/resources/frame_044.png differ diff --git a/resources/frame_045.png b/resources/frame_045.png index abccb19..3516bb7 100644 Binary files a/resources/frame_045.png and b/resources/frame_045.png differ diff --git a/resources/frame_046.png b/resources/frame_046.png index f68f720..6417c3a 100644 Binary files a/resources/frame_046.png and b/resources/frame_046.png differ diff --git a/resources/frame_047.png b/resources/frame_047.png index 021c3bd..52a6e05 100644 Binary files a/resources/frame_047.png and b/resources/frame_047.png differ diff --git a/resources/frame_048.png b/resources/frame_048.png index 9e5710c..22b33c9 100644 Binary files a/resources/frame_048.png and b/resources/frame_048.png differ diff --git a/resources/frame_049.png b/resources/frame_049.png index 0a4bf9d..0210887 100644 Binary files a/resources/frame_049.png and b/resources/frame_049.png differ diff --git a/resources/frame_050.png b/resources/frame_050.png index 0f11cb7..6bc7f71 100644 Binary files a/resources/frame_050.png and b/resources/frame_050.png differ diff --git a/resources/frame_051.png b/resources/frame_051.png index c752123..c113a38 100644 Binary files a/resources/frame_051.png and b/resources/frame_051.png differ diff --git a/resources/frame_052.png b/resources/frame_052.png index 2d5bd28..64dfcb0 100644 Binary files a/resources/frame_052.png and b/resources/frame_052.png differ diff --git a/resources/frame_053.png b/resources/frame_053.png index 8ce453b..4c579cf 100644 Binary files a/resources/frame_053.png and b/resources/frame_053.png differ diff --git a/resources/frame_054.png b/resources/frame_054.png index 47fda1f..9d00563 100644 Binary files a/resources/frame_054.png and b/resources/frame_054.png differ diff --git a/resources/frame_055.png b/resources/frame_055.png index bc8db6f..5da283c 100644 Binary files a/resources/frame_055.png and b/resources/frame_055.png differ diff --git a/resources/frame_056.png b/resources/frame_056.png index de442ce..b1d494a 100644 Binary files a/resources/frame_056.png and b/resources/frame_056.png differ diff --git a/resources/frame_057.png b/resources/frame_057.png index 647c528..61e7435 100644 Binary files a/resources/frame_057.png and b/resources/frame_057.png differ diff --git a/resources/frame_058.png b/resources/frame_058.png index 31e30e9..1061af7 100644 Binary files a/resources/frame_058.png and b/resources/frame_058.png differ diff --git a/resources/frame_059.png b/resources/frame_059.png index 31e30e9..1061af7 100644 Binary files a/resources/frame_059.png and b/resources/frame_059.png differ diff --git a/resources/frame_060.png b/resources/frame_060.png index 31e30e9..1061af7 100644 Binary files a/resources/frame_060.png and b/resources/frame_060.png differ diff --git a/resources/frame_061.png b/resources/frame_061.png index 0aefa1d..1afc009 100644 Binary files a/resources/frame_061.png and b/resources/frame_061.png differ diff --git a/resources/frame_062.png b/resources/frame_062.png index 6454143..27317a4 100644 Binary files a/resources/frame_062.png and b/resources/frame_062.png differ diff --git a/resources/pwr50k.png b/resources/pwr50k.png new file mode 100644 index 0000000..0625a78 Binary files /dev/null and b/resources/pwr50k.png differ diff --git a/resources/pwr70k.png b/resources/pwr70k.png new file mode 100644 index 0000000..aa4d498 Binary files /dev/null and b/resources/pwr70k.png differ diff --git a/resources/pwr90k.png b/resources/pwr90k.png new file mode 100644 index 0000000..e8aa3b8 Binary files /dev/null and b/resources/pwr90k.png differ diff --git a/resources/pwrpsx1.png b/resources/pwrpsx1.png new file mode 100644 index 0000000..840e405 Binary files /dev/null and b/resources/pwrpsx1.png differ diff --git a/resources/pwrpsx2.png b/resources/pwrpsx2.png new file mode 100644 index 0000000..d6179cf Binary files /dev/null and b/resources/pwrpsx2.png differ diff --git a/resources/pwrtvcombo.png b/resources/pwrtvcombo.png new file mode 100644 index 0000000..437bedf Binary files /dev/null and b/resources/pwrtvcombo.png differ diff --git a/ui.c b/ui.c index e24171e..d5ac02d 100644 --- a/ui.c +++ b/ui.c @@ -27,214 +27,214 @@ FT_Face face; extern int gsKit_texture_finish(GSGLOBAL *gsGlobal, GSTEXTURE *Texture); void draw_bitmap(int x, int y, FT_Bitmap *bitmap, GSTEXTURE *Texture, u32 color) { - memset(Texture, 0, sizeof(GSTEXTURE)); - - Texture->Delayed = 1; - Texture->PSM = GS_PSM_CT32; - Texture->Filter = GS_FILTER_NEAREST; - Texture->VramClut = 0; - Texture->Clut = NULL; - - Texture->Width = bitmap->width; - Texture->Height = bitmap->rows; - u32 TextureSize = gsKit_texture_size_ee(Texture->Width, Texture->Height, Texture->PSM); - Texture->Mem = memalign(128, TextureSize); - - u32 *buff = (u32 *) Texture->Mem; - - memset(buff, 0, TextureSize); - - if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) - { - for (FT_Int i = 0; i < bitmap->rows; i++) - { - for (FT_Int j = 0; j < bitmap->width; j++) - { - u8 cl = 0xFF - bitmap->buffer[i * bitmap->width + j]; - buff[i * bitmap->width + j] = cl << 24 | color; - } - } - } - - gsKit_texture_finish(gsGlobal, Texture); - - gsKit_TexManager_bind(gsGlobal, Texture); - - gsKit_prim_sprite_texture(gsGlobal, Texture, x, y, 0.0f, 0.0f, x + Texture->Width, y + Texture->Height, Texture->Width, Texture->Height, 3, GS_SETREG_RGBAQ(0xFF,0xFF,0xFF,0xFF,0x00)); + memset(Texture, 0, sizeof(GSTEXTURE)); + + Texture->Delayed = 1; + Texture->PSM = GS_PSM_CT32; + Texture->Filter = GS_FILTER_NEAREST; + Texture->VramClut = 0; + Texture->Clut = NULL; + + Texture->Width = bitmap->width; + Texture->Height = bitmap->rows; + u32 TextureSize = gsKit_texture_size_ee(Texture->Width, Texture->Height, Texture->PSM); + Texture->Mem = memalign(128, TextureSize); + + u32 *buff = (u32 *)Texture->Mem; + + memset(buff, 0, TextureSize); + + if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) + { + for (FT_Int i = 0; i < bitmap->rows; i++) + { + for (FT_Int j = 0; j < bitmap->width; j++) + { + u8 cl = 0xFF - bitmap->buffer[i * bitmap->width + j]; + buff[i * bitmap->width + j] = cl << 24 | color; + } + } + } + + gsKit_texture_finish(gsGlobal, Texture); + + gsKit_TexManager_bind(gsGlobal, Texture); + + gsKit_prim_sprite_texture(gsGlobal, Texture, x, y, 0.0f, 0.0f, x + Texture->Width, y + Texture->Height, Texture->Width, Texture->Height, 3, GS_SETREG_RGBAQ(0xFF, 0xFF, 0xFF, 0xFF, 0x00)); } -struct GSTEXTURE_holder *drawImage(int x, int y, int width, int height, u8 *texture) +struct GSTEXTURE_holder *drawImage(int x, int y, int width, int height, const u8 *texture) { - struct GSTEXTURE_holder *TextureHolder = malloc(sizeof(struct GSTEXTURE_holder)); - memset(TextureHolder, 0, sizeof(struct GSTEXTURE_holder)); - GSTEXTURE *Texture = &TextureHolder->curr; - - memset(Texture, 0, sizeof(GSTEXTURE)); - - Texture->Delayed = 1; - Texture->PSM = GS_PSM_CT32; - Texture->Filter = GS_FILTER_NEAREST; - Texture->VramClut = 0; - Texture->Clut = NULL; - - Texture->Width = width; - Texture->Height = height; - u32 TextureSize = gsKit_texture_size_ee(Texture->Width, Texture->Height, Texture->PSM); - Texture->Mem = memalign(128, TextureSize); - - uint32_t pos = 0; - uint32_t tx = 0; - uint32_t ty = 0; - - uint32_t hw = 0; - while(hw < height * width) - { - uint8_t count = texture[pos]; - pos += 1; - - char repeat_run = count & 0x80; - count = (count & 0x7f) + 1; - - for (int i = 0; i < count; i++) - { - Texture->Mem[ty * width + tx] = (texture[pos] << 16) | (texture[pos+1] << 8) | texture[pos+2]; - hw += 1; - tx += 1; - - if (!repeat_run) - pos += 3; - } - - if (repeat_run) - pos += 3; - - if(tx == width) - { - ty += 1; - tx = 0; - } - } - - gsKit_texture_finish(gsGlobal, Texture); - - gsKit_TexManager_bind(gsGlobal, Texture); - - gsKit_prim_sprite_texture(gsGlobal, Texture, x, y, 0.0f, 0.0f, x + Texture->Width, y + Texture->Height, Texture->Width, Texture->Height, 3, GS_SETREG_RGBAQ(0xFF,0xFF,0xFF,0xFF,0x00)); - - return TextureHolder; + struct GSTEXTURE_holder *TextureHolder = malloc(sizeof(struct GSTEXTURE_holder)); + memset(TextureHolder, 0, sizeof(struct GSTEXTURE_holder)); + GSTEXTURE *Texture = &TextureHolder->curr; + + memset(Texture, 0, sizeof(GSTEXTURE)); + + Texture->Delayed = 1; + Texture->PSM = GS_PSM_CT32; + Texture->Filter = GS_FILTER_NEAREST; + Texture->VramClut = 0; + Texture->Clut = NULL; + + Texture->Width = width; + Texture->Height = height; + u32 TextureSize = gsKit_texture_size_ee(Texture->Width, Texture->Height, Texture->PSM); + Texture->Mem = memalign(128, TextureSize); + + uint32_t pos = 0; + uint32_t tx = 0; + uint32_t ty = 0; + + uint32_t hw = 0; + while (hw < height * width) + { + uint8_t count = texture[pos]; + pos += 1; + + char repeat_run = count & 0x80; + count = (count & 0x7f) + 1; + + for (int i = 0; i < count; i++) + { + Texture->Mem[ty * width + tx] = (texture[pos] << 16) | (texture[pos + 1] << 8) | texture[pos + 2]; + hw += 1; + tx += 1; + + if (!repeat_run) + pos += 3; + } + + if (repeat_run) + pos += 3; + + if (tx == width) + { + ty += 1; + tx = 0; + } + } + + gsKit_texture_finish(gsGlobal, Texture); + + gsKit_TexManager_bind(gsGlobal, Texture); + + gsKit_prim_sprite_texture(gsGlobal, Texture, x, y, 0.0f, 0.0f, x + Texture->Width, y + Texture->Height, Texture->Width, Texture->Height, 3, GS_SETREG_RGBAQ(0xFF, 0xFF, 0xFF, 0xFF, 0x00)); + + return TextureHolder; } void getTextSize(int size, const char *text, int *x, int *y) { - FT_GlyphSlot slot = face->glyph; - u32 text_len = strlen(text); - - FT_Set_Pixel_Sizes(face, 0, size); - - *x = 0; - *y = 0; - - for (int n = 0; n < text_len; n++) - { - int error = FT_Load_Char(face, text[n], FT_LOAD_RENDER); - if (error) - continue; - - *x += slot->advance.x >> 6; - *y += slot->advance.y >> 6; - } + FT_GlyphSlot slot = face->glyph; + u32 text_len = strlen(text); + + FT_Set_Pixel_Sizes(face, 0, size); + + *x = 0; + *y = 0; + + for (int n = 0; n < text_len; n++) + { + int error = FT_Load_Char(face, text[n], FT_LOAD_RENDER); + if (error) + continue; + + *x += slot->advance.x >> 6; + *y += slot->advance.y >> 6; + } } struct GSTEXTURE_holder *draw_text(int x, int y, int size, u32 color, const char *text) { - FT_GlyphSlot slot = face->glyph; - u32 text_len = strlen(text); - - FT_Set_Pixel_Sizes(face, 0, size); - - if (x < 0 || y < 0) - { - int size_x, size_y; - getTextSize(size, text, &size_x, &size_y); - - if (x < 0) - x += gsGlobal->Width - size_x; - if (y < 0) - y += gsGlobal->Height - size_y; - } - - y += size; - - struct GSTEXTURE_holder *Textures = 0; - for (int n = 0; n < text_len; n++) - { - int error = FT_Load_Char(face, text[n], FT_LOAD_RENDER); - if (error) - continue; - - struct GSTEXTURE_holder *Texture = malloc(sizeof(struct GSTEXTURE_holder)); - memset(Texture, 0, sizeof(struct GSTEXTURE_holder)); - draw_bitmap(x + slot->bitmap_left, y - slot->bitmap_top, &slot->bitmap, &Texture->curr, color); - - Texture->next = Textures; - Textures = Texture; - - x += slot->advance.x >> 6; - y += slot->advance.y >> 6; - } - - return Textures; + FT_GlyphSlot slot = face->glyph; + u32 text_len = strlen(text); + + FT_Set_Pixel_Sizes(face, 0, size); + + if (x < 0 || y < 0) + { + int size_x, size_y; + getTextSize(size, text, &size_x, &size_y); + + if (x < 0) + x += gsGlobal->Width - size_x; + if (y < 0) + y += gsGlobal->Height - size_y; + } + + y += size; + + struct GSTEXTURE_holder *Textures = 0; + for (int n = 0; n < text_len; n++) + { + int error = FT_Load_Char(face, text[n], FT_LOAD_RENDER); + if (error) + continue; + + struct GSTEXTURE_holder *Texture = malloc(sizeof(struct GSTEXTURE_holder)); + memset(Texture, 0, sizeof(struct GSTEXTURE_holder)); + draw_bitmap(x + slot->bitmap_left, y - slot->bitmap_top, &slot->bitmap, &Texture->curr, color); + + Texture->next = Textures; + Textures = Texture; + + x += slot->advance.x >> 6; + y += slot->advance.y >> 6; + } + + return Textures; } struct GSTEXTURE_holder *ui_printf(int x, int y, int size, u32 color, const char *format, ...) { - char buffer[256]; - va_list args; - va_start(args, format); - vsprintf(buffer, format, args); - struct GSTEXTURE_holder *Textures = draw_text(x, y, size, color, buffer); - va_end(args); - return Textures; + char buffer[256]; + va_list args; + va_start(args, format); + vsprintf(buffer, format, args); + struct GSTEXTURE_holder *Textures = draw_text(x, y, size, color, buffer); + va_end(args); + return Textures; } void freeGSTEXTURE_holder(struct GSTEXTURE_holder *Textures) -{ - while (Textures) - { - struct GSTEXTURE_holder *next = Textures->next; - gsKit_TexManager_free(gsGlobal, &Textures->curr); - if (Textures->curr.Mem) - free(Textures->curr.Mem); - free(Textures); - Textures = next; - } +{ + while (Textures) + { + struct GSTEXTURE_holder *next = Textures->next; + gsKit_TexManager_free(gsGlobal, &Textures->curr); + if (Textures->curr.Mem) + free(Textures->curr.Mem); + free(Textures); + Textures = next; + } } void drawFrame() { - gsKit_queue_exec(gsGlobal); + gsKit_queue_exec(gsGlobal); - gsKit_sync_flip(gsGlobal); + gsKit_sync_flip(gsGlobal); - gsKit_TexManager_nextFrame(gsGlobal); + gsKit_TexManager_nextFrame(gsGlobal); } void init_ui() { - gsGlobal = gsKit_init_global(); + gsGlobal = gsKit_init_global(); - gsGlobal->PSM = GS_PSM_CT24; - gsGlobal->PSMZ = GS_PSMZ_16S; - gsGlobal->PrimAlphaEnable = GS_SETTING_ON; + gsGlobal->PSM = GS_PSM_CT24; + gsGlobal->PSMZ = GS_PSMZ_16S; + gsGlobal->PrimAlphaEnable = GS_SETTING_ON; - dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, - D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF); + dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, + D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF); - dmaKit_chan_init(DMA_CHANNEL_GIF); + dmaKit_chan_init(DMA_CHANNEL_GIF); - gsKit_init_screen(gsGlobal); - - int error = FT_Init_FreeType(&library); + gsKit_init_screen(gsGlobal); - error = FT_New_Memory_Face(library, &IndieFlower, size_IndieFlower, 0, &face); + int error = FT_Init_FreeType(&library); + // TODO: add error haandling + error = FT_New_Memory_Face(library, &IndieFlower, size_IndieFlower, 0, &face); } diff --git a/ui.h b/ui.h index 57015da..3707ffc 100644 --- a/ui.h +++ b/ui.h @@ -17,27 +17,28 @@ #include #include #include +#include -#define White GS_SETREG_RGBAQ(0xFF,0xFF,0xFF,0x00,0x00) -#define Black GS_SETREG_RGBAQ(0x00,0x00,0x00,0x00,0x00) -#define Red GS_SETREG_RGBAQ(0xFF,0x00,0x00,0x00,0x00) -#define Green GS_SETREG_RGBAQ(0x00,0xFF,0x00,0x00,0x00) -#define Blue GS_SETREG_RGBAQ(0x00,0x00,0xFF,0x00,0x00) +#define White GS_SETREG_RGBAQ(0xFF, 0xFF, 0xFF, 0x00, 0x00) +#define Black GS_SETREG_RGBAQ(0x00, 0x00, 0x00, 0x00, 0x00) +#define Red GS_SETREG_RGBAQ(0xFF, 0x00, 0x00, 0x00, 0x00) +#define Green GS_SETREG_RGBAQ(0x00, 0xFF, 0x00, 0x00, 0x00) +#define Blue GS_SETREG_RGBAQ(0x00, 0x00, 0xFF, 0x00, 0x00) -#define BlueTrans GS_SETREG_RGBAQ(0x00,0x00,0xFF,0x40,0x00) -#define RedTrans GS_SETREG_RGBAQ(0xFF,0x00,0x00,0x60,0x00) -#define GreenTrans GS_SETREG_RGBAQ(0x00,0xFF,0x00,0x50,0x00) -#define WhiteTrans GS_SETREG_RGBAQ(0xFF,0xFF,0xFF,0x50,0x00) +#define BlueTrans GS_SETREG_RGBAQ(0x00, 0x00, 0xFF, 0x40, 0x00) +#define RedTrans GS_SETREG_RGBAQ(0xFF, 0x00, 0x00, 0x60, 0x00) +#define GreenTrans GS_SETREG_RGBAQ(0x00, 0xFF, 0x00, 0x50, 0x00) +#define WhiteTrans GS_SETREG_RGBAQ(0xFF, 0xFF, 0xFF, 0x50, 0x00) struct GSTEXTURE_holder { - GSTEXTURE curr; - struct GSTEXTURE_holder *next; + GSTEXTURE curr; + struct GSTEXTURE_holder *next; }; extern GSGLOBAL *gsGlobal; -struct GSTEXTURE_holder *drawImage(int x, int y, int width, int height, u8 *texture); +struct GSTEXTURE_holder *drawImage(int x, int y, int width, int height, const u8 *texture); void getTextSize(int size, const char *text, int *x, int *y);