├── FPGA.jpg ├── PCB.jpg ├── README.md ├── dldi ├── G003.dldi ├── code.asm ├── code.bin └── iointerface.c ├── dumps ├── dump_a0.bin ├── dump_e0.bin └── dump_f0.bin ├── fcore ├── decrypt.py └── key.bin ├── files ├── F_CORE_V410.DAT ├── F_CORE_V450.DAT ├── M3GUpdaterPlus_450HW.nds └── M3GUpdaterPlus_450HW.txt └── tools ├── z003_dump ├── Makefile └── source │ └── main.c ├── z003_flash ├── Makefile └── source │ ├── cart_commands.c │ ├── cart_commands.h │ └── main.c └── z003_ntrboot ├── Makefile ├── README.md ├── data └── blowfish_retail.bin ├── screenshot.jpg └── source ├── cart_commands.c ├── cart_commands.h └── main.c /FPGA.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/FPGA.jpg -------------------------------------------------------------------------------- /PCB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/PCB.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Synopsis 2 | 3 | Set of information and tools whilst working with my M3i Zero (`GMP-Z003`) and 4 | it's firmware. Use this information however you want. 5 | 6 | ## Hardware 7 | 8 | Image of the carts PCB 9 | Image of the FPGA 10 | 11 | ### Flash Memory 12 | 13 | The `GMP-Z003` uses a `MX29LV160DBXEI-70G` for flash memory, it is a 2MB chip. 14 | This device operates over a voltage range of 2.7V to 3.6V typically using a 3V 15 | power supply input. The flash memory is read directly to the NDS as a cartridge, 16 | the format of which can be found [here](http://problemkaputt.de/gbatek.htm#dsicartridgeheader). 17 | It is writeable through the flashing process. 18 | 19 | ### Flashing 20 | 21 | The device can be flashed by providing DC power to the `J3` port. I just stripped 22 | a USB cable and put the positive and ground in. The FPGA searches 23 | the SD card for `/F_CORE.DAT` and copies `0x200000 -> 0x400000` to the flash 24 | memory chip. I believe the `F_CORE.DAT` needs to be signed in order for the 25 | FPGA to copy it first however. 26 | 27 | The LED light `D1` will change depending on the status of the flash: 28 | * Nothing: No power or completed 29 | * Static: Error reading `F_CORE.DAT` (SD card might not be inserted, etc..) 30 | * Flashing: Copying `F_CORE.DAT` to the flash memory. 31 | 32 | Alternatively the device can be flashed whilst inserted via the DS itself 33 | using card commands. 34 | 35 | ### Card Commands 36 | 37 | The common DLDI interface for the flash cart can be found here: [G003.dldi](dldi/G003.dldi) 38 | And the reconstructed C source of that DLDI interface can be found here: [iointerface.c](dldi/iointerface.c) 39 | 40 | * `B0 00 00 00 00 00 00 00` = Card Info (should be 0x5AA5) 41 | * `C9 oo oo oo oo xx 00 00` = Read (FIFO read 0x200 words) 42 | * `C5 oo oo oo oo xx 00 00` = Write (write 0x200 words) 43 | * `C6 00 00 00 00 00 00 00` = get write status, read 1 word (= 0 when finished) 44 | * `CA 00 00 00 00 00 00 00` = get read status, read 1 word (= 0 when finished) 45 | 46 | Where `oooooo` is the offset in number of words(?), MSB first 47 | Where `xx` represents the type in the DLDI interface this is set to `0x00` for SD card access. 48 | * `0x00` : SD card access afaik. 49 | * `0xE0`: "SW" header, used with offset = 0, after that offset += 0x10000 (in number of words) 50 | * `0xF0`: "SW" regular sector (0x200 bytes) 51 | * `0xA0`: "HW" sector. One sector (header ?) is at 0x80000000 then the others start at offset 0. 52 | 53 | 54 | ### Credits 55 | 56 | * [TuxSH](https://github.com/TuxSH) for everything on card commands. -------------------------------------------------------------------------------- /dldi/G003.dldi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/dldi/G003.dldi -------------------------------------------------------------------------------- /dldi/code.asm: -------------------------------------------------------------------------------- 1 | ; DLDI 2 | ; G003DS - Revolution for DS 3 | ; DLDI_SIZE_8KB 4 | ; FIX_ALL | FIX_GLUE | FIX_GOT | FIX_BSS 5 | 6 | ; dldiStart: 0xBF800000 7 | ; dldiEnd: 0xBF8009D0 8 | ; interworkStart: 0xBF800098 9 | ; interworkEnd: 0xBF800098 10 | ; gotStart: 0xBF8009CC 11 | ; gotEnd: 0xBF8009CC 12 | ; bssStart: 0xBF8009D0 13 | ; bssEnd: 0xBF8009EC 14 | 15 | ; DISC_INTERFACE_STRUCT { 16 | ; ioType: G003 17 | ; features: 0x23 18 | ; startup: 0xBF8008BC 19 | ; isInserted: 0xBF8008E4 20 | ; readSectors: 0xBF80090C 21 | ; writeSectors: 0xBF800950 22 | ; clearStatus: 0xBF800994 23 | ; shutdown: 0xBF80099C 24 | ; } 25 | 26 | ; .code 0xBF800080 27 | ; .code end 0xBF8009D0 28 | 29 | .data:bf800080 0d c0 a0 e1 mov r12, sp 30 | .data:bf800084 f8 df 2d e9 push {r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr, pc} 31 | .data:bf800088 04 b0 4c e2 sub r11, r12, #4 32 | .data:bf80008c 28 d0 4b e2 sub sp, r11, #40 ; 0x28 33 | .data:bf800090 f0 6f 9d e8 ldm sp, {r4, r5, r6, r7, r8, r9, r10, r11, sp, lr} 34 | .data:bf800094 1e ff 2f e1 bx lr 35 | .data:bf800098 10 40 2d e9 push {r4, lr} 36 | .data:bf80009c 2c 40 9f e5 ldr r4, [pc, #44] ; 0xbf8000d0 37 | .data:bf8000a0 00 30 d4 e5 ldrb r3, [r4] 38 | .data:bf8000a4 00 00 53 e3 cmp r3, #0 39 | .data:bf8000a8 24 20 9f e5 ldr r2, [pc, #36] ; 0xbf8000d4 40 | .data:bf8000ac 05 00 00 1a bne 0xbf8000c8 41 | .data:bf8000b0 00 00 52 e3 cmp r2, #0 42 | .data:bf8000b4 1c 00 9f e5 ldr r0, [pc, #28] ; 0xbf8000d8 43 | .data:bf8000b8 0f e0 a0 11 movne lr, pc 44 | .data:bf8000bc 12 ff 2f 11 bxne r2 45 | .data:bf8000c0 01 30 a0 e3 mov r3, #1 46 | .data:bf8000c4 00 30 c4 e5 strb r3, [r4] 47 | .data:bf8000c8 10 40 bd e8 pop {r4, lr} 48 | .data:bf8000cc 1e ff 2f e1 bx lr 49 | .data:bf8000d0 d0 09 80 bf svclt 0x008009d0 50 | .data:bf8000d4 00 00 00 00 andeq r0, r0, r0 51 | .data:bf8000d8 c4 09 80 bf svclt 0x008009c4 52 | .data:bf8000dc 04 e0 2d e5 push {lr} ; (str lr, [sp, #-4]!) 53 | .data:bf8000e0 40 30 9f e5 ldr r3, [pc, #64] ; 0xbf800128 54 | .data:bf8000e4 00 00 53 e3 cmp r3, #0 55 | .data:bf8000e8 04 d0 4d e2 sub sp, sp, #4 56 | .data:bf8000ec 38 00 9f e5 ldr r0, [pc, #56] ; 0xbf80012c 57 | .data:bf8000f0 38 10 9f e5 ldr r1, [pc, #56] ; 0xbf800130 58 | .data:bf8000f4 0f e0 a0 11 movne lr, pc 59 | .data:bf8000f8 13 ff 2f 11 bxne r3 60 | .data:bf8000fc 30 00 9f e5 ldr r0, [pc, #48] ; 0xbf800134 61 | .data:bf800100 00 30 90 e5 ldr r3, [r0] 62 | .data:bf800104 00 00 53 e3 cmp r3, #0 63 | .data:bf800108 28 30 9f e5 ldr r3, [pc, #40] ; 0xbf800138 64 | .data:bf80010c 02 00 00 0a beq 0xbf80011c 65 | .data:bf800110 00 00 53 e3 cmp r3, #0 66 | .data:bf800114 0f e0 a0 11 movne lr, pc 67 | .data:bf800118 13 ff 2f 11 bxne r3 68 | .data:bf80011c 04 d0 8d e2 add sp, sp, #4 69 | .data:bf800120 04 e0 9d e4 pop {lr} ; (ldr lr, [sp], #4) 70 | .data:bf800124 1e ff 2f e1 bx lr 71 | .data:bf800128 00 00 00 00 andeq r0, r0, r0 72 | .data:bf80012c c4 09 80 bf svclt 0x008009c4 73 | .data:bf800130 d4 09 80 bf svclt 0x008009d4 74 | .data:bf800134 c8 09 80 bf svclt 0x008009c8 75 | .data:bf800138 00 00 00 00 andeq r0, r0, r0 76 | .data:bf80013c 01 23 a0 e3 mov r2, #67108864 ; 0x4000000 77 | .data:bf800140 a4 31 92 e5 ldr r3, [r2, #420] ; 0x1a4 78 | .data:bf800144 00 00 53 e3 cmp r3, #0 79 | .data:bf800148 fc ff ff ba blt 0xbf800140 80 | .data:bf80014c 3f 30 e0 e3 mvn r3, #63 ; 0x3f 81 | .data:bf800150 6b 1f a0 e3 mov r1, #428 ; 0x1ac 82 | .data:bf800154 a1 31 c2 e5 strb r3, [r2, #417] ; 0x1a1 83 | .data:bf800158 c1 13 81 e2 add r1, r1, #67108867 ; 0x4000003 84 | .data:bf80015c 00 20 a0 e3 mov r2, #0 85 | .data:bf800160 02 30 d0 e7 ldrb r3, [r0, r2] 86 | .data:bf800164 01 20 82 e2 add r2, r2, #1 87 | .data:bf800168 08 00 52 e3 cmp r2, #8 88 | .data:bf80016c 01 30 41 e4 strb r3, [r1], #-1 89 | .data:bf800170 fa ff ff 1a bne 0xbf800160 90 | .data:bf800174 1e ff 2f e1 bx lr 91 | .data:bf800178 70 40 2d e9 push {r4, r5, r6, lr} 92 | .data:bf80017c 03 40 a0 e1 mov r4, r3 93 | .data:bf800180 02 61 81 e0 add r6, r1, r2, lsl #2 94 | .data:bf800184 01 50 a0 e1 mov r5, r1 95 | .data:bf800188 eb ff ff eb bl 0xbf80013c 96 | .data:bf80018c 01 33 a0 e3 mov r3, #67108864 ; 0x4000000 97 | .data:bf800190 a4 41 83 e5 str r4, [r3, #420] ; 0x1a4 98 | .data:bf800194 03 20 a0 e1 mov r2, r3 99 | .data:bf800198 41 16 a0 e3 mov r1, #68157440 ; 0x4100000 100 | .data:bf80019c a4 31 92 e5 ldr r3, [r2, #420] ; 0x1a4 101 | .data:bf8001a0 02 05 13 e3 tst r3, #8388608 ; 0x800000 102 | .data:bf8001a4 04 00 00 0a beq 0xbf8001bc 103 | .data:bf8001a8 00 00 55 e3 cmp r5, #0 104 | .data:bf8001ac 06 00 55 11 cmpne r5, r6 105 | .data:bf8001b0 10 30 91 35 ldrcc r3, [r1, #16] 106 | .data:bf8001b4 10 30 91 25 ldrcs r3, [r1, #16] 107 | .data:bf8001b8 04 30 85 34 strcc r3, [r5], #4 108 | .data:bf8001bc a4 31 92 e5 ldr r3, [r2, #420] ; 0x1a4 109 | .data:bf8001c0 00 00 53 e3 cmp r3, #0 110 | .data:bf8001c4 f4 ff ff ba blt 0xbf80019c 111 | .data:bf8001c8 70 40 bd e8 pop {r4, r5, r6, lr} 112 | .data:bf8001cc 1e ff 2f e1 bx lr 113 | .data:bf8001d0 f0 41 2d e9 push {r4, r5, r6, r7, r8, lr} 114 | .data:bf8001d4 00 80 a0 e1 mov r8, r0 115 | .data:bf8001d8 01 70 a0 e1 mov r7, r1 116 | .data:bf8001dc 00 50 a0 e3 mov r5, #0 117 | .data:bf8001e0 01 43 a0 e3 mov r4, #67108864 ; 0x4000000 118 | .data:bf8001e4 41 66 a0 e3 mov r6, #68157440 ; 0x4100000 119 | .data:bf8001e8 07 00 a0 e1 mov r0, r7 120 | .data:bf8001ec d2 ff ff eb bl 0xbf80013c 121 | .data:bf8001f0 a4 81 84 e5 str r8, [r4, #420] ; 0x1a4 122 | .data:bf8001f4 a4 31 94 e5 ldr r3, [r4, #420] ; 0x1a4 123 | .data:bf8001f8 02 05 13 e3 tst r3, #8388608 ; 0x800000 124 | .data:bf8001fc 02 00 00 0a beq 0xbf80020c 125 | .data:bf800200 10 30 96 e5 ldr r3, [r6, #16] 126 | .data:bf800204 00 00 53 e3 cmp r3, #0 127 | .data:bf800208 01 50 a0 03 moveq r5, #1 128 | .data:bf80020c a4 31 94 e5 ldr r3, [r4, #420] ; 0x1a4 129 | .data:bf800210 00 00 53 e3 cmp r3, #0 130 | .data:bf800214 f6 ff ff ba blt 0xbf8001f4 131 | .data:bf800218 00 00 55 e3 cmp r5, #0 132 | .data:bf80021c f1 ff ff 0a beq 0xbf8001e8 133 | .data:bf800220 f0 41 bd e8 pop {r4, r5, r6, r7, r8, lr} 134 | .data:bf800224 1e ff 2f e1 bx lr 135 | .data:bf800228 70 40 2d e9 push {r4, r5, r6, lr} 136 | .data:bf80022c 00 40 a0 e1 mov r4, r0 137 | .data:bf800230 03 00 a0 e1 mov r0, r3 138 | .data:bf800234 02 61 81 e0 add r6, r1, r2, lsl #2 139 | .data:bf800238 01 50 a0 e1 mov r5, r1 140 | .data:bf80023c be ff ff eb bl 0xbf80013c 141 | .data:bf800240 01 33 a0 e3 mov r3, #67108864 ; 0x4000000 142 | .data:bf800244 a4 41 83 e5 str r4, [r3, #420] ; 0x1a4 143 | .data:bf800248 03 20 a0 e1 mov r2, r3 144 | .data:bf80024c 41 16 a0 e3 mov r1, #68157440 ; 0x4100000 145 | .data:bf800250 a4 31 92 e5 ldr r3, [r2, #420] ; 0x1a4 146 | .data:bf800254 02 05 13 e3 tst r3, #8388608 ; 0x800000 147 | .data:bf800258 03 00 00 0a beq 0xbf80026c 148 | .data:bf80025c 10 30 91 e5 ldr r3, [r1, #16] 149 | .data:bf800260 06 00 55 e1 cmp r5, r6 150 | .data:bf800264 00 30 85 35 strcc r3, [r5] 151 | .data:bf800268 04 50 85 e2 add r5, r5, #4 152 | .data:bf80026c a4 31 92 e5 ldr r3, [r2, #420] ; 0x1a4 153 | .data:bf800270 00 00 53 e3 cmp r3, #0 154 | .data:bf800274 f5 ff ff ba blt 0xbf800250 155 | .data:bf800278 70 40 bd e8 pop {r4, r5, r6, lr} 156 | .data:bf80027c 1e ff 2f e1 bx lr 157 | .data:bf800280 70 40 2d e9 push {r4, r5, r6, lr} 158 | .data:bf800284 00 40 a0 e1 mov r4, r0 159 | .data:bf800288 03 00 a0 e1 mov r0, r3 160 | .data:bf80028c 01 50 a0 e1 mov r5, r1 161 | .data:bf800290 02 61 81 e0 add r6, r1, r2, lsl #2 162 | .data:bf800294 a8 ff ff eb bl 0xbf80013c 163 | .data:bf800298 01 33 a0 e3 mov r3, #67108864 ; 0x4000000 164 | .data:bf80029c a4 41 83 e5 str r4, [r3, #420] ; 0x1a4 165 | .data:bf8002a0 03 c0 a0 e1 mov r12, r3 166 | .data:bf8002a4 41 e6 a0 e3 mov lr, #68157440 ; 0x4100000 167 | .data:bf8002a8 a4 31 9c e5 ldr r3, [r12, #420] ; 0x1a4 168 | .data:bf8002ac 02 05 13 e3 tst r3, #8388608 ; 0x800000 169 | .data:bf8002b0 09 00 00 0a beq 0xbf8002dc 170 | .data:bf8002b4 10 30 9e e5 ldr r3, [lr, #16] 171 | .data:bf8002b8 06 00 55 e1 cmp r5, r6 172 | .data:bf8002bc 23 0c a0 e1 lsr r0, r3, #24 173 | .data:bf8002c0 23 24 a0 e1 lsr r2, r3, #8 174 | .data:bf8002c4 23 18 a0 e1 lsr r1, r3, #16 175 | .data:bf8002c8 01 20 c5 35 strbcc r2, [r5, #1] 176 | .data:bf8002cc 02 10 c5 35 strbcc r1, [r5, #2] 177 | .data:bf8002d0 03 00 c5 35 strbcc r0, [r5, #3] 178 | .data:bf8002d4 00 30 c5 35 strbcc r3, [r5] 179 | .data:bf8002d8 04 50 85 e2 add r5, r5, #4 180 | .data:bf8002dc a4 31 9c e5 ldr r3, [r12, #420] ; 0x1a4 181 | .data:bf8002e0 00 00 53 e3 cmp r3, #0 182 | .data:bf8002e4 ef ff ff ba blt 0xbf8002a8 183 | .data:bf8002e8 70 40 bd e8 pop {r4, r5, r6, lr} 184 | .data:bf8002ec 1e ff 2f e1 bx lr 185 | .data:bf8002f0 f0 40 2d e9 push {r4, r5, r6, r7, lr} 186 | .data:bf8002f4 3d 30 e0 e3 mvn r3, #61 ; 0x3d 187 | .data:bf8002f8 14 d0 4d e2 sub sp, sp, #20 188 | .data:bf8002fc 02 70 a0 e1 mov r7, r2 189 | .data:bf800300 00 e0 a0 e3 mov lr, #0 190 | .data:bf800304 20 28 a0 e1 lsr r2, r0, #16 191 | .data:bf800308 20 c4 a0 e1 lsr r12, r0, #8 192 | .data:bf80030c 10 50 8d e2 add r5, sp, #16 193 | .data:bf800310 0b 30 cd e5 strb r3, [sp, #11] 194 | .data:bf800314 3d 30 83 e2 add r3, r3, #61 ; 0x3d 195 | .data:bf800318 20 4c a0 e1 lsr r4, r0, #24 196 | .data:bf80031c 09 20 cd e5 strb r2, [sp, #9] 197 | .data:bf800320 08 c0 cd e5 strb r12, [sp, #8] 198 | .data:bf800324 05 e0 cd e5 strb lr, [sp, #5] 199 | .data:bf800328 04 30 25 e5 str r3, [r5, #-4]! 200 | .data:bf80032c 0a 70 cd e5 strb r7, [sp, #10] 201 | .data:bf800330 07 00 cd e5 strb r0, [sp, #7] 202 | .data:bf800334 06 e0 cd e5 strb lr, [sp, #6] 203 | .data:bf800338 04 40 cd e5 strb r4, [sp, #4] 204 | .data:bf80033c 01 60 a0 e1 mov r6, r1 205 | .data:bf800340 04 40 8d e2 add r4, sp, #4 206 | .data:bf800344 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 207 | .data:bf800348 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 208 | .data:bf80034c 04 30 a0 e1 mov r3, r4 209 | .data:bf800350 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 210 | .data:bf800354 05 10 a0 e1 mov r1, r5 211 | .data:bf800358 01 20 a0 e3 mov r2, #1 212 | .data:bf80035c b1 ff ff eb bl 0xbf800228 213 | .data:bf800360 0c 30 9d e5 ldr r3, [sp, #12] 214 | .data:bf800364 00 00 53 e3 cmp r3, #0 215 | .data:bf800368 f5 ff ff 1a bne 0xbf800344 216 | .data:bf80036c 3d 30 43 e2 sub r3, r3, #61 ; 0x3d 217 | .data:bf800370 03 00 16 e3 tst r6, #3 218 | .data:bf800374 0b 30 cd e5 strb r3, [sp, #11] 219 | .data:bf800378 09 00 00 0a beq 0xbf8003a4 220 | .data:bf80037c a1 04 a0 e3 mov r0, #-1593835520 ; 0xa1000000 221 | .data:bf800380 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 222 | .data:bf800384 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 223 | .data:bf800388 06 10 a0 e1 mov r1, r6 224 | .data:bf80038c a7 20 a0 e1 lsr r2, r7, #1 225 | .data:bf800390 04 30 a0 e1 mov r3, r4 226 | .data:bf800394 b9 ff ff eb bl 0xbf800280 227 | .data:bf800398 14 d0 8d e2 add sp, sp, #20 228 | .data:bf80039c f0 40 bd e8 pop {r4, r5, r6, r7, lr} 229 | .data:bf8003a0 1e ff 2f e1 bx lr 230 | .data:bf8003a4 a1 04 a0 e3 mov r0, #-1593835520 ; 0xa1000000 231 | .data:bf8003a8 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 232 | .data:bf8003ac 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 233 | .data:bf8003b0 06 10 a0 e1 mov r1, r6 234 | .data:bf8003b4 a7 20 a0 e1 lsr r2, r7, #1 235 | .data:bf8003b8 04 30 a0 e1 mov r3, r4 236 | .data:bf8003bc 99 ff ff eb bl 0xbf800228 237 | .data:bf8003c0 f4 ff ff ea b 0xbf800398 238 | .data:bf8003c4 f0 41 2d e9 push {r4, r5, r6, r7, r8, lr} 239 | .data:bf8003c8 08 d0 4d e2 sub sp, sp, #8 240 | .data:bf8003cc 00 c0 a0 e1 mov r12, r0 241 | .data:bf8003d0 20 e4 a0 e1 lsr lr, r0, #8 242 | .data:bf8003d4 32 30 e0 e3 mvn r3, #50 ; 0x32 243 | .data:bf8003d8 01 70 a0 e1 mov r7, r1 244 | .data:bf8003dc 20 6c a0 e1 lsr r6, r0, #24 245 | .data:bf8003e0 20 18 a0 e1 lsr r1, r0, #16 246 | .data:bf8003e4 00 40 a0 e3 mov r4, #0 247 | .data:bf8003e8 0d 00 a0 e1 mov r0, sp 248 | .data:bf8003ec a2 50 a0 e1 lsr r5, r2, #1 249 | .data:bf8003f0 07 30 cd e5 strb r3, [sp, #7] 250 | .data:bf8003f4 06 20 cd e5 strb r2, [sp, #6] 251 | .data:bf8003f8 04 e0 cd e5 strb lr, [sp, #4] 252 | .data:bf8003fc 03 c0 cd e5 strb r12, [sp, #3] 253 | .data:bf800400 05 10 cd e5 strb r1, [sp, #5] 254 | .data:bf800404 00 60 cd e5 strb r6, [sp] 255 | .data:bf800408 02 40 cd e5 strb r4, [sp, #2] 256 | .data:bf80040c 01 40 cd e5 strb r4, [sp, #1] 257 | .data:bf800410 49 ff ff eb bl 0xbf80013c 258 | .data:bf800414 e1 34 a0 e3 mov r3, #-520093696 ; 0xe1000000 259 | .data:bf800418 16 37 83 e2 add r3, r3, #5767168 ; 0x580000 260 | .data:bf80041c 01 23 a0 e3 mov r2, #67108864 ; 0x4000000 261 | .data:bf800420 06 3a 83 e2 add r3, r3, #24576 ; 0x6000 262 | .data:bf800424 a4 31 82 e5 str r3, [r2, #420] ; 0x1a4 263 | .data:bf800428 0d 80 a0 e1 mov r8, sp 264 | .data:bf80042c 05 51 87 e0 add r5, r7, r5, lsl #2 265 | .data:bf800430 02 c0 a0 e1 mov r12, r2 266 | .data:bf800434 41 e6 a0 e3 mov lr, #68157440 ; 0x4100000 267 | .data:bf800438 a4 31 9c e5 ldr r3, [r12, #420] ; 0x1a4 268 | .data:bf80043c 02 05 13 e3 tst r3, #8388608 ; 0x800000 269 | .data:bf800440 0d 00 00 0a beq 0xbf80047c 270 | .data:bf800444 05 00 57 e1 cmp r7, r5 271 | .data:bf800448 09 00 00 2a bcs 0xbf800474 272 | .data:bf80044c 03 00 17 e3 tst r7, #3 273 | .data:bf800450 03 30 d7 15 ldrbne r3, [r7, #3] 274 | .data:bf800454 00 20 d7 15 ldrbne r2, [r7] 275 | .data:bf800458 01 10 d7 15 ldrbne r1, [r7, #1] 276 | .data:bf80045c 02 00 d7 15 ldrbne r0, [r7, #2] 277 | .data:bf800460 03 3c a0 11 lslne r3, r3, #24 278 | .data:bf800464 01 24 82 11 orrne r2, r2, r1, lsl #8 279 | .data:bf800468 00 38 83 11 orrne r3, r3, r0, lsl #16 280 | .data:bf80046c 00 40 97 05 ldreq r4, [r7] 281 | .data:bf800470 03 40 82 11 orrne r4, r2, r3 282 | .data:bf800474 10 40 8e e5 str r4, [lr, #16] 283 | .data:bf800478 04 70 87 e2 add r7, r7, #4 284 | .data:bf80047c a4 31 9c e5 ldr r3, [r12, #420] ; 0x1a4 285 | .data:bf800480 00 00 53 e3 cmp r3, #0 286 | .data:bf800484 eb ff ff ba blt 0xbf800438 287 | .data:bf800488 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 288 | .data:bf80048c 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 289 | .data:bf800490 31 30 e0 e3 mvn r3, #49 ; 0x31 290 | .data:bf800494 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 291 | .data:bf800498 0d 10 a0 e1 mov r1, sp 292 | .data:bf80049c 07 30 cd e5 strb r3, [sp, #7] 293 | .data:bf8004a0 4a ff ff eb bl 0xbf8001d0 294 | .data:bf8004a4 08 d0 8d e2 add sp, sp, #8 295 | .data:bf8004a8 f0 41 bd e8 pop {r4, r5, r6, r7, r8, lr} 296 | .data:bf8004ac 1e ff 2f e1 bx lr 297 | .data:bf8004b0 04 e0 2d e5 push {lr} ; (str lr, [sp, #-4]!) 298 | .data:bf8004b4 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 299 | .data:bf8004b8 0c d0 4d e2 sub sp, sp, #12 300 | .data:bf8004bc 00 30 a0 e3 mov r3, #0 301 | .data:bf8004c0 3c 20 a0 e3 mov r2, #60 ; 0x3c 302 | .data:bf8004c4 61 09 80 e2 add r0, r0, #1589248 ; 0x184000 303 | .data:bf8004c8 0d 10 a0 e1 mov r1, sp 304 | .data:bf8004cc 07 20 cd e5 strb r2, [sp, #7] 305 | .data:bf8004d0 00 30 cd e5 strb r3, [sp] 306 | .data:bf8004d4 06 30 cd e5 strb r3, [sp, #6] 307 | .data:bf8004d8 05 30 cd e5 strb r3, [sp, #5] 308 | .data:bf8004dc 04 30 cd e5 strb r3, [sp, #4] 309 | .data:bf8004e0 03 30 cd e5 strb r3, [sp, #3] 310 | .data:bf8004e4 02 30 cd e5 strb r3, [sp, #2] 311 | .data:bf8004e8 01 30 cd e5 strb r3, [sp, #1] 312 | .data:bf8004ec 37 ff ff eb bl 0xbf8001d0 313 | .data:bf8004f0 0c d0 8d e2 add sp, sp, #12 314 | .data:bf8004f4 04 e0 9d e4 pop {lr} ; (ldr lr, [sp], #4) 315 | .data:bf8004f8 1e ff 2f e1 bx lr 316 | .data:bf8004fc 04 e0 2d e5 push {lr} ; (str lr, [sp, #-4]!) 317 | .data:bf800500 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 318 | .data:bf800504 0c d0 4d e2 sub sp, sp, #12 319 | .data:bf800508 61 09 80 e2 add r0, r0, #1589248 ; 0x184000 320 | .data:bf80050c 00 30 a0 e3 mov r3, #0 321 | .data:bf800510 6f 20 e0 e3 mvn r2, #111 ; 0x6f 322 | .data:bf800514 02 0a 80 e2 add r0, r0, #8192 ; 0x2000 323 | .data:bf800518 0d 10 a0 e1 mov r1, sp 324 | .data:bf80051c 07 20 cd e5 strb r2, [sp, #7] 325 | .data:bf800520 00 30 cd e5 strb r3, [sp] 326 | .data:bf800524 06 30 cd e5 strb r3, [sp, #6] 327 | .data:bf800528 05 30 cd e5 strb r3, [sp, #5] 328 | .data:bf80052c 04 30 cd e5 strb r3, [sp, #4] 329 | .data:bf800530 03 30 cd e5 strb r3, [sp, #3] 330 | .data:bf800534 02 30 cd e5 strb r3, [sp, #2] 331 | .data:bf800538 01 30 cd e5 strb r3, [sp, #1] 332 | .data:bf80053c 23 ff ff eb bl 0xbf8001d0 333 | .data:bf800540 0c d0 8d e2 add sp, sp, #12 334 | .data:bf800544 04 e0 9d e4 pop {lr} ; (ldr lr, [sp], #4) 335 | .data:bf800548 1e ff 2f e1 bx lr 336 | .data:bf80054c 04 e0 2d e5 push {lr} ; (str lr, [sp, #-4]!) 337 | .data:bf800550 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 338 | .data:bf800554 0c d0 4d e2 sub sp, sp, #12 339 | .data:bf800558 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 340 | .data:bf80055c 00 30 a0 e3 mov r3, #0 341 | .data:bf800560 6f 20 e0 e3 mvn r2, #111 ; 0x6f 342 | .data:bf800564 01 09 80 e2 add r0, r0, #16384 ; 0x4000 343 | .data:bf800568 0d 10 a0 e1 mov r1, sp 344 | .data:bf80056c 07 20 cd e5 strb r2, [sp, #7] 345 | .data:bf800570 00 30 cd e5 strb r3, [sp] 346 | .data:bf800574 06 30 cd e5 strb r3, [sp, #6] 347 | .data:bf800578 05 30 cd e5 strb r3, [sp, #5] 348 | .data:bf80057c 04 30 cd e5 strb r3, [sp, #4] 349 | .data:bf800580 03 30 cd e5 strb r3, [sp, #3] 350 | .data:bf800584 02 30 cd e5 strb r3, [sp, #2] 351 | .data:bf800588 01 30 cd e5 strb r3, [sp, #1] 352 | .data:bf80058c 0f ff ff eb bl 0xbf8001d0 353 | .data:bf800590 0c d0 8d e2 add sp, sp, #12 354 | .data:bf800594 04 e0 9d e4 pop {lr} ; (ldr lr, [sp], #4) 355 | .data:bf800598 1e ff 2f e1 bx lr 356 | .data:bf80059c f0 43 2d e9 push {r4, r5, r6, r7, r8, r9, lr} 357 | .data:bf8005a0 00 c0 a0 e1 mov r12, r0 358 | .data:bf8005a4 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 359 | .data:bf8005a8 14 d0 4d e2 sub sp, sp, #20 360 | .data:bf8005ac 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 361 | .data:bf8005b0 01 40 a0 e1 mov r4, r1 362 | .data:bf8005b4 2c ec a0 e1 lsr lr, r12, #24 363 | .data:bf8005b8 2c 58 a0 e1 lsr r5, r12, #16 364 | .data:bf8005bc 2c 64 a0 e1 lsr r6, r12, #8 365 | .data:bf8005c0 21 7c a0 e1 lsr r7, r1, #24 366 | .data:bf8005c4 21 88 a0 e1 lsr r8, r1, #16 367 | .data:bf8005c8 21 94 a0 e1 lsr r9, r1, #8 368 | .data:bf8005cc 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 369 | .data:bf8005d0 0c 10 8d e2 add r1, sp, #12 370 | .data:bf8005d4 01 20 a0 e3 mov r2, #1 371 | .data:bf8005d8 04 30 8d e2 add r3, sp, #4 372 | .data:bf8005dc 0b e0 cd e5 strb lr, [sp, #11] 373 | .data:bf8005e0 0a 50 cd e5 strb r5, [sp, #10] 374 | .data:bf8005e4 09 60 cd e5 strb r6, [sp, #9] 375 | .data:bf8005e8 08 c0 cd e5 strb r12, [sp, #8] 376 | .data:bf8005ec 07 70 cd e5 strb r7, [sp, #7] 377 | .data:bf8005f0 06 80 cd e5 strb r8, [sp, #6] 378 | .data:bf8005f4 05 90 cd e5 strb r9, [sp, #5] 379 | .data:bf8005f8 04 40 cd e5 strb r4, [sp, #4] 380 | .data:bf8005fc 09 ff ff eb bl 0xbf800228 381 | .data:bf800600 0c 00 9d e5 ldr r0, [sp, #12] 382 | .data:bf800604 14 d0 8d e2 add sp, sp, #20 383 | .data:bf800608 f0 43 bd e8 pop {r4, r5, r6, r7, r8, r9, lr} 384 | .data:bf80060c 1e ff 2f e1 bx lr 385 | .data:bf800610 04 e0 2d e5 push {lr} ; (str lr, [sp, #-4]!) 386 | .data:bf800614 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 387 | .data:bf800618 14 d0 4d e2 sub sp, sp, #20 388 | .data:bf80061c 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 389 | .data:bf800620 00 c0 a0 e3 mov r12, #0 390 | .data:bf800624 4f e0 e0 e3 mvn lr, #79 ; 0x4f 391 | .data:bf800628 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 392 | .data:bf80062c 0c 10 8d e2 add r1, sp, #12 393 | .data:bf800630 01 20 a0 e3 mov r2, #1 394 | .data:bf800634 04 30 8d e2 add r3, sp, #4 395 | .data:bf800638 0b e0 cd e5 strb lr, [sp, #11] 396 | .data:bf80063c 04 c0 cd e5 strb r12, [sp, #4] 397 | .data:bf800640 0a c0 cd e5 strb r12, [sp, #10] 398 | .data:bf800644 09 c0 cd e5 strb r12, [sp, #9] 399 | .data:bf800648 08 c0 cd e5 strb r12, [sp, #8] 400 | .data:bf80064c 07 c0 cd e5 strb r12, [sp, #7] 401 | .data:bf800650 06 c0 cd e5 strb r12, [sp, #6] 402 | .data:bf800654 05 c0 cd e5 strb r12, [sp, #5] 403 | .data:bf800658 f2 fe ff eb bl 0xbf800228 404 | .data:bf80065c 0c 00 9d e5 ldr r0, [sp, #12] 405 | .data:bf800660 14 d0 8d e2 add sp, sp, #20 406 | .data:bf800664 04 e0 9d e4 pop {lr} ; (ldr lr, [sp], #4) 407 | .data:bf800668 1e ff 2f e1 bx lr 408 | 409 | ; func 410 | .data:bf80066c f0 41 2d e9 push {r4, r5, r6, r7, r8, lr} 411 | .data:bf800670 00 c0 a0 e1 mov r12, r0 412 | .data:bf800674 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 413 | .data:bf800678 08 d0 4d e2 sub sp, sp, #8 414 | .data:bf80067c 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 415 | .data:bf800680 00 40 a0 e3 mov r4, #0 416 | .data:bf800684 ac e7 a0 e1 lsr lr, r12, #15 417 | .data:bf800688 ac 53 a0 e1 lsr r5, r12, #7 418 | .data:bf80068c 36 30 e0 e3 mvn r3, #54 ; 0x36 419 | .data:bf800690 01 70 a0 e1 mov r7, r1 420 | .data:bf800694 ac 6b a0 e1 lsr r6, r12, #23 421 | .data:bf800698 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 422 | .data:bf80069c 8c c0 a0 e1 lsl r12, r12, #1 423 | .data:bf8006a0 0d 10 a0 e1 mov r1, sp 424 | .data:bf8006a4 07 30 cd e5 strb r3, [sp, #7] 425 | .data:bf8006a8 05 50 cd e5 strb r5, [sp, #5] 426 | .data:bf8006ac 06 e0 cd e5 strb lr, [sp, #6] 427 | .data:bf8006b0 04 c0 cd e5 strb r12, [sp, #4] 428 | .data:bf8006b4 01 40 cd e5 strb r4, [sp, #1] 429 | .data:bf8006b8 00 60 cd e5 strb r6, [sp] 430 | .data:bf8006bc 02 50 a0 e1 mov r5, r2 431 | .data:bf8006c0 03 40 cd e5 strb r4, [sp, #3] 432 | .data:bf8006c4 02 40 cd e5 strb r4, [sp, #2] 433 | .data:bf8006c8 c0 fe ff eb bl 0xbf8001d0 434 | .data:bf8006cc 35 30 e0 e3 mvn r3, #53 ; 0x35 435 | .data:bf8006d0 03 00 17 e3 tst r7, #3 436 | .data:bf8006d4 0d 80 a0 e1 mov r8, sp 437 | .data:bf8006d8 07 30 cd e5 strb r3, [sp, #7] 438 | .data:bf8006dc 17 00 00 1a bne 0xbf800740 439 | .data:bf8006e0 09 35 47 e2 sub r3, r7, #37748736 ; 0x2400000 440 | .data:bf8006e4 01 05 53 e3 cmp r3, #4194304 ; 0x400000 441 | .data:bf8006e8 02 04 57 23 cmpcs r7, #33554432 ; 0x2000000 442 | .data:bf8006ec 01 00 00 3a bcc 0xbf8006f8 443 | .data:bf8006f0 80 00 55 e3 cmp r5, #128 ; 0x80 444 | .data:bf8006f4 19 00 00 0a beq 0xbf800760 445 | .data:bf8006f8 0d 00 a0 e1 mov r0, sp 446 | .data:bf8006fc 8e fe ff eb bl 0xbf80013c 447 | .data:bf800700 a1 34 a0 e3 mov r3, #-1593835520 ; 0xa1000000 448 | .data:bf800704 16 37 83 e2 add r3, r3, #5767168 ; 0x580000 449 | .data:bf800708 06 3a 83 e2 add r3, r3, #24576 ; 0x6000 450 | .data:bf80070c 01 23 a0 e3 mov r2, #67108864 ; 0x4000000 451 | .data:bf800710 a4 31 82 e5 str r3, [r2, #420] ; 0x1a4 452 | .data:bf800714 41 16 a0 e3 mov r1, #68157440 ; 0x4100000 453 | .data:bf800718 a4 31 92 e5 ldr r3, [r2, #420] ; 0x1a4 454 | .data:bf80071c 02 05 13 e3 tst r3, #8388608 ; 0x800000 455 | .data:bf800720 10 30 91 15 ldrne r3, [r1, #16] 456 | .data:bf800724 04 30 87 14 strne r3, [r7], #4 457 | .data:bf800728 a4 31 92 e5 ldr r3, [r2, #420] ; 0x1a4 458 | .data:bf80072c 00 00 53 e3 cmp r3, #0 459 | .data:bf800730 f8 ff ff ba blt 0xbf800718 460 | .data:bf800734 08 d0 8d e2 add sp, sp, #8 461 | .data:bf800738 f0 41 bd e8 pop {r4, r5, r6, r7, r8, lr} 462 | .data:bf80073c 1e ff 2f e1 bx lr 463 | .data:bf800740 a1 04 a0 e3 mov r0, #-1593835520 ; 0xa1000000 464 | .data:bf800744 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 465 | .data:bf800748 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 466 | .data:bf80074c 07 10 a0 e1 mov r1, r7 467 | .data:bf800750 05 20 a0 e1 mov r2, r5 468 | .data:bf800754 0d 30 a0 e1 mov r3, sp 469 | .data:bf800758 c8 fe ff eb bl 0xbf800280 470 | .data:bf80075c f4 ff ff ea b 0xbf800734 471 | .data:bf800760 a1 04 a0 e3 mov r0, #-1593835520 ; 0xa1000000 472 | .data:bf800764 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 473 | .data:bf800768 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 474 | .data:bf80076c 07 10 a0 e1 mov r1, r7 475 | .data:bf800770 05 20 a0 e1 mov r2, r5 476 | .data:bf800774 0d 30 a0 e1 mov r3, sp 477 | .data:bf800778 aa fe ff eb bl 0xbf800228 478 | .data:bf80077c ec ff ff ea b 0xbf800734 479 | 480 | ; func 481 | .data:bf800780 f0 40 2d e9 push {r4, r5, r6, r7, lr} 482 | .data:bf800784 0c d0 4d e2 sub sp, sp, #12 483 | .data:bf800788 a0 e7 a0 e1 lsr lr, r0, #15 484 | .data:bf80078c 80 c0 a0 e1 lsl r12, r0, #1 485 | .data:bf800790 a0 6b a0 e1 lsr r6, r0, #23 486 | .data:bf800794 00 40 a0 e3 mov r4, #0 487 | .data:bf800798 a0 53 a0 e1 lsr r5, r0, #7 488 | .data:bf80079c 3a 30 e0 e3 mvn r3, #58 ; 0x3a 489 | .data:bf8007a0 0d 00 a0 e1 mov r0, sp 490 | .data:bf8007a4 07 30 cd e5 strb r3, [sp, #7] 491 | .data:bf8007a8 06 e0 cd e5 strb lr, [sp, #6] 492 | .data:bf8007ac 05 50 cd e5 strb r5, [sp, #5] 493 | .data:bf8007b0 04 c0 cd e5 strb r12, [sp, #4] 494 | .data:bf8007b4 02 50 a0 e1 mov r5, r2 495 | .data:bf8007b8 00 60 cd e5 strb r6, [sp] 496 | .data:bf8007bc 03 40 cd e5 strb r4, [sp, #3] 497 | .data:bf8007c0 01 60 a0 e1 mov r6, r1 498 | .data:bf8007c4 02 40 cd e5 strb r4, [sp, #2] 499 | .data:bf8007c8 01 40 cd e5 strb r4, [sp, #1] 500 | .data:bf8007cc 5a fe ff eb bl 0xbf80013c 501 | .data:bf8007d0 e1 34 a0 e3 mov r3, #-520093696 ; 0xe1000000 502 | .data:bf8007d4 16 37 83 e2 add r3, r3, #5767168 ; 0x580000 503 | .data:bf8007d8 01 23 a0 e3 mov r2, #67108864 ; 0x4000000 504 | .data:bf8007dc 06 3a 83 e2 add r3, r3, #24576 ; 0x6000 505 | .data:bf8007e0 a4 31 82 e5 str r3, [r2, #420] ; 0x1a4 506 | .data:bf8007e4 05 e1 86 e0 add lr, r6, r5, lsl #2 507 | .data:bf8007e8 0d 70 a0 e1 mov r7, sp 508 | .data:bf8007ec 02 c0 a0 e1 mov r12, r2 509 | .data:bf8007f0 41 56 a0 e3 mov r5, #68157440 ; 0x4100000 510 | .data:bf8007f4 a4 31 9c e5 ldr r3, [r12, #420] ; 0x1a4 511 | .data:bf8007f8 02 05 13 e3 tst r3, #8388608 ; 0x800000 512 | .data:bf8007fc 0d 00 00 0a beq 0xbf800838 513 | .data:bf800800 0e 00 56 e1 cmp r6, lr 514 | .data:bf800804 09 00 00 2a bcs 0xbf800830 515 | .data:bf800808 03 00 16 e3 tst r6, #3 516 | .data:bf80080c 03 30 d6 15 ldrbne r3, [r6, #3] 517 | .data:bf800810 00 20 d6 15 ldrbne r2, [r6] 518 | .data:bf800814 01 10 d6 15 ldrbne r1, [r6, #1] 519 | .data:bf800818 02 00 d6 15 ldrbne r0, [r6, #2] 520 | .data:bf80081c 03 3c a0 11 lslne r3, r3, #24 521 | .data:bf800820 01 24 82 11 orrne r2, r2, r1, lsl #8 522 | .data:bf800824 00 38 83 11 orrne r3, r3, r0, lsl #16 523 | .data:bf800828 00 40 96 05 ldreq r4, [r6] 524 | .data:bf80082c 03 40 82 11 orrne r4, r2, r3 525 | .data:bf800830 10 40 85 e5 str r4, [r5, #16] 526 | .data:bf800834 04 60 86 e2 add r6, r6, #4 527 | .data:bf800838 a4 31 9c e5 ldr r3, [r12, #420] ; 0x1a4 528 | .data:bf80083c 00 00 53 e3 cmp r3, #0 529 | .data:bf800840 eb ff ff ba blt 0xbf8007f4 530 | .data:bf800844 a7 04 a0 e3 mov r0, #-1493172224 ; 0xa7000000 531 | .data:bf800848 16 07 80 e2 add r0, r0, #5767168 ; 0x580000 532 | .data:bf80084c 39 30 e0 e3 mvn r3, #57 ; 0x39 533 | .data:bf800850 06 0a 80 e2 add r0, r0, #24576 ; 0x6000 534 | .data:bf800854 0d 10 a0 e1 mov r1, sp 535 | .data:bf800858 07 30 cd e5 strb r3, [sp, #7] 536 | .data:bf80085c 5b fe ff eb bl 0xbf8001d0 537 | .data:bf800860 0c d0 8d e2 add sp, sp, #12 538 | .data:bf800864 f0 40 bd e8 pop {r4, r5, r6, r7, lr} 539 | .data:bf800868 1e ff 2f e1 bx lr 540 | .data:bf80086c 30 40 2d e9 push {r4, r5, lr} 541 | .data:bf800870 0f 10 01 e2 and r1, r1, #15 542 | .data:bf800874 81 12 a0 e1 lsl r1, r1, #5 543 | .data:bf800878 a0 3b a0 e1 lsr r3, r0, #23 544 | .data:bf80087c 80 14 81 e0 add r1, r1, r0, lsl #9 545 | .data:bf800880 0f 20 02 e2 and r2, r2, #15 546 | .data:bf800884 ff 30 03 e2 and r3, r3, #255 ; 0xff 547 | .data:bf800888 02 3c 83 e1 orr r3, r3, r2, lsl #24 548 | .data:bf80088c 21 24 a0 e1 lsr r2, r1, #8 549 | .data:bf800890 04 d0 4d e2 sub sp, sp, #4 550 | .data:bf800894 01 5c 83 e1 orr r5, r3, r1, lsl #24 551 | .data:bf800898 2d 43 82 e3 orr r4, r2, #-1275068416 ; 0xb4000000 552 | .data:bf80089c 04 00 a0 e1 mov r0, r4 553 | .data:bf8008a0 05 10 a0 e1 mov r1, r5 554 | .data:bf8008a4 3c ff ff eb bl 0xbf80059c 555 | .data:bf8008a8 00 00 50 e3 cmp r0, #0 556 | .data:bf8008ac fa ff ff 1a bne 0xbf80089c 557 | .data:bf8008b0 04 d0 8d e2 add sp, sp, #4 558 | .data:bf8008b4 30 40 bd e8 pop {r4, r5, lr} 559 | .data:bf8008b8 1e ff 2f e1 bx lr 560 | 561 | ; bool startup(void) 562 | .data:bf8008bc 04 e0 2d e5 push {lr} ; (str lr, [sp, #-4]!) 563 | .data:bf8008c0 04 d0 4d e2 sub sp, sp, #4 564 | .data:bf8008c4 51 ff ff eb bl 0xbf800610 565 | .data:bf8008c8 07 00 00 e2 and r0, r0, #7 566 | .data:bf8008cc 04 00 50 e3 cmp r0, #4 567 | .data:bf8008d0 00 00 a0 13 movne r0, #0 568 | .data:bf8008d4 01 00 a0 03 moveq r0, #1 569 | .data:bf8008d8 04 d0 8d e2 add sp, sp, #4 570 | .data:bf8008dc 04 e0 9d e4 pop {lr} ; (ldr lr, [sp], #4) 571 | .data:bf8008e0 1e ff 2f e1 bx lr 572 | 573 | ; bool isInserted(void) 574 | .data:bf8008e4 04 e0 2d e5 push {lr} ; (str lr, [sp, #-4]!) 575 | .data:bf8008e8 04 d0 4d e2 sub sp, sp, #4 576 | .data:bf8008ec 47 ff ff eb bl 0xbf800610 577 | .data:bf8008f0 07 00 00 e2 and r0, r0, #7 578 | .data:bf8008f4 04 00 50 e3 cmp r0, #4 579 | .data:bf8008f8 00 00 a0 13 movne r0, #0 580 | .data:bf8008fc 01 00 a0 03 moveq r0, #1 581 | .data:bf800900 04 d0 8d e2 add sp, sp, #4 582 | .data:bf800904 04 e0 9d e4 pop {lr} ; (ldr lr, [sp], #4) 583 | .data:bf800908 1e ff 2f e1 bx lr 584 | 585 | ; bool readSectors(sec_t sector, sec_t numSectors, void* buffer) 586 | .data:bf80090c 00 30 51 e2 subs r3, r1, #0 587 | .data:bf800910 70 40 2d e9 push {r4, r5, r6, lr} 588 | .data:bf800914 0a 00 00 0a beq 0xbf800944 589 | .data:bf800918 00 40 a0 e1 mov r4, r0 590 | .data:bf80091c 02 50 a0 e1 mov r5, r2 591 | .data:bf800920 03 60 80 e0 add r6, r0, r3 592 | .data:bf800924 04 00 a0 e1 mov r0, r4 593 | .data:bf800928 05 10 a0 e1 mov r1, r5 594 | .data:bf80092c 01 40 84 e2 add r4, r4, #1 595 | .data:bf800930 80 20 a0 e3 mov r2, #128 ; 0x80 596 | .data:bf800934 4c ff ff eb bl 0xbf80066c 597 | .data:bf800938 04 00 56 e1 cmp r6, r4 598 | .data:bf80093c 02 5c 85 e2 add r5, r5, #512 ; 0x200 599 | .data:bf800940 f7 ff ff 1a bne 0xbf800924 600 | .data:bf800944 01 00 a0 e3 mov r0, #1 601 | .data:bf800948 70 40 bd e8 pop {r4, r5, r6, lr} 602 | .data:bf80094c 1e ff 2f e1 bx lr 603 | 604 | 605 | ; bool writeSectors(sec_t sector, sec_t numSectors, const void* buffer) 606 | .data:bf800950 00 30 51 e2 subs r3, r1, #0 607 | .data:bf800954 70 40 2d e9 push {r4, r5, r6, lr} 608 | .data:bf800958 0a 00 00 0a beq 0xbf800988 609 | .data:bf80095c 00 40 a0 e1 mov r4, r0 610 | .data:bf800960 02 50 a0 e1 mov r5, r2 611 | .data:bf800964 03 60 80 e0 add r6, r0, r3 612 | .data:bf800968 04 00 a0 e1 mov r0, r4 613 | .data:bf80096c 05 10 a0 e1 mov r1, r5 614 | .data:bf800970 01 40 84 e2 add r4, r4, #1 615 | .data:bf800974 80 20 a0 e3 mov r2, #128 ; 0x80 616 | .data:bf800978 80 ff ff eb bl 0xbf800780 617 | .data:bf80097c 04 00 56 e1 cmp r6, r4 618 | .data:bf800980 02 5c 85 e2 add r5, r5, #512 ; 0x200 619 | .data:bf800984 f7 ff ff 1a bne 0xbf800968 620 | .data:bf800988 01 00 a0 e3 mov r0, #1 621 | .data:bf80098c 70 40 bd e8 pop {r4, r5, r6, lr} 622 | .data:bf800990 1e ff 2f e1 bx lr 623 | 624 | ; bool clearStatus(void) 625 | .data:bf800994 01 00 a0 e3 mov r0, #1 626 | .data:bf800998 1e ff 2f e1 bx lr 627 | 628 | ; bool shutdown(void) 629 | .data:bf80099c 01 00 a0 e3 mov r0, #1 630 | .data:bf8009a0 1e ff 2f e1 bx lr 631 | .data:bf8009a4 0d c0 a0 e1 mov r12, sp 632 | .data:bf8009a8 f8 df 2d e9 push {r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr, pc} 633 | .data:bf8009ac 04 b0 4c e2 sub r11, r12, #4 634 | .data:bf8009b0 28 d0 4b e2 sub sp, r11, #40 ; 0x28 635 | .data:bf8009b4 f0 6f 9d e8 ldm sp, {r4, r5, r6, r7, r8, r9, r10, r11, sp, lr} 636 | .data:bf8009b8 1e ff 2f e1 bx lr 637 | .data:bf8009bc dc 00 80 bf svclt 0x008000dc 638 | .data:bf8009c0 98 00 80 bf svclt 0x00800098 639 | .data:bf8009c4 00 00 00 00 andeq r0, r0, r0 640 | .data:bf8009c8 00 00 00 00 andeq r0, r0, r0 641 | .data:bf8009cc 00 00 00 00 andeq r0, r0, r0 -------------------------------------------------------------------------------- /dldi/code.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/dldi/code.bin -------------------------------------------------------------------------------- /dldi/iointerface.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void ioM3CardWaitReady(u32 flags, u8 *command) 4 | { 5 | bool ready = false; 6 | 7 | do { 8 | cardWriteCommand(command); 9 | REG_ROMCTRL = flags; 10 | do { 11 | if (REG_ROMCTRL & CARD_DATA_READY) 12 | if (!CARD_DATA_RD) ready = true; 13 | } while (REG_ROMCTRL & CARD_BUSY); 14 | } while (!ready); 15 | } 16 | 17 | void ioM3ByteCardPolledTransfer(uint32 flags, uint32 * destination, uint32 length, uint8 * command) 18 | { 19 | u32 data;; 20 | cardWriteCommand(command); 21 | REG_ROMCTRL = flags; 22 | uint32 * target = destination + length; 23 | do { 24 | // Read data if available 25 | if (REG_ROMCTRL & CARD_DATA_READY) { 26 | data=CARD_DATA_RD; 27 | if (destination < target) { 28 | ((uint8*)destination)[0] = data & 0xff; 29 | ((uint8*)destination)[1] = (data >> 8) & 0xff; 30 | ((uint8*)destination)[2] = (data >> 16) & 0xff; 31 | ((uint8*)destination)[3] = (data >> 24) & 0xff; 32 | } 33 | destination++; 34 | } 35 | } while (REG_ROMCTRL & CARD_BUSY); 36 | } 37 | 38 | void ioM3LogicCardRead(u32 address, u32 *destination, u32 length) 39 | { 40 | u8 command[8]; 41 | 42 | command[7] = 0xC9; // GMP-Z003 43 | command[6] = (address >> 24) & 0xff; 44 | command[5] = (address >> 16) & 0xff; 45 | command[4] = (address >> 8) & 0xff; 46 | command[3] = address & 0xff; 47 | command[2] = 0; 48 | command[1] = 0; 49 | command[0] = 0; 50 | ioR4CardWaitReady(0xa7586000, command); 51 | command[7] = 0xCA; // GMP-Z003 52 | if ((u32)destination & 0x03) 53 | ioM3ByteCardPolledTransfer(0xa1586000, destination, length, command); 54 | else // read logic might not be perfect.. 55 | cardPolledTransfer(0xa1586000, destination, length, command); 56 | } 57 | 58 | void ioM3LogicCardWrite(u32 address, u32 *source, u32 length) 59 | { 60 | u8 command[8]; 61 | u32 data = 0; 62 | 63 | command[7] = 0xC5; // GMP-Z003 64 | command[6] = (address >> 24) & 0xff; 65 | command[5] = (address >> 16) & 0xff; 66 | command[4] = (address >> 8) & 0xff; 67 | command[3] = address & 0xff; 68 | command[2] = 0; 69 | command[1] = 0; 70 | command[0] = 0; 71 | cardWriteCommand(command); 72 | REG_ROMCTRL = 0xe1586000; 73 | u32 * target = source + length; 74 | do { 75 | // Write data if ready 76 | if (REG_ROMCTRL & CARD_DATA_READY) { 77 | if (source < target) { 78 | if ((u32)source & 0x03) 79 | data = ((uint8*)source)[0] | (((uint8*)source)[1] << 8) | (((uint8*)source)[2] << 16) | (((uint8*)source)[3] << 24); 80 | else 81 | data = *source; 82 | } 83 | source++; 84 | CARD_DATA_RD = data; 85 | } 86 | } while (REG_ROMCTRL & CARD_BUSY); 87 | command[7] = 0xC6; // GMP-Z003 88 | ioM3CardWaitReady(0xa7586000, command); 89 | } 90 | 91 | u32 ioM3ReadCardInfo(void) 92 | { 93 | u8 command[8]; 94 | u32 ret; 95 | 96 | command[7] = 0xb0; // GMP-Z003 97 | command[6] = 0; 98 | command[5] = 0; 99 | command[4] = 0; 100 | command[3] = 0; 101 | command[2] = 0; 102 | command[1] = 0; 103 | command[0] = 0; 104 | cardPolledTransfer(0xa7586000, &ret, 1, command); 105 | return ret; 106 | } 107 | 108 | bool startup(void) 109 | { 110 | return (ioM3ReadCardInfo() & 0x07) == 0x04; 111 | } 112 | 113 | bool isInserted(void) 114 | { 115 | return (ioM3ReadCardInfo() & 0x07) == 0x04; 116 | } 117 | 118 | bool readSectors(u32 sector, u32 numSecs, void* buffer) 119 | { 120 | u32 *u32_buffer = (u32*)buffer, i; 121 | 122 | for (i = 0; i < numSecs; i++) { 123 | ioM3LogicCardRead(sector << 9, u32_buffer, 128); 124 | sector++; 125 | u32_buffer += 128; 126 | } 127 | return true; 128 | } 129 | 130 | bool writeSectors(u32 sector, u32 numSecs, void* buffer) 131 | { 132 | u32 *u32_buffer = (u32*)buffer, i; 133 | 134 | for (i = 0; i < numSecs; i++) { 135 | ioM3LogicCardWrite(sector << 9, u32_buffer, 128); 136 | sector++; 137 | u32_buffer += 128; 138 | } 139 | return true; 140 | } 141 | 142 | bool clearStatus(void) 143 | { 144 | return true; 145 | } 146 | 147 | bool shutdown(void) 148 | { 149 | return true; 150 | } -------------------------------------------------------------------------------- /dumps/dump_a0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/dumps/dump_a0.bin -------------------------------------------------------------------------------- /dumps/dump_e0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/dumps/dump_e0.bin -------------------------------------------------------------------------------- /dumps/dump_f0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/dumps/dump_f0.bin -------------------------------------------------------------------------------- /fcore/decrypt.py: -------------------------------------------------------------------------------- 1 | import array 2 | import struct 3 | import sys 4 | 5 | # 0x000000 -> 0x200000 Encrypted NDS ROM 6 | # 0x184000 -> 0x200000 Encrypted Passcard4 ROM 7 | 8 | # 0x200000 -> 0x400000 NDS ROM 9 | # 0x380000 -> 0x400000 Passcard4 ROM 10 | 11 | # 0x400000 -> 0x600000 FF filled with 512 byte end 12 | 13 | # collect params 14 | infilename = sys.argv[1] if len(sys.argv) > 1 else 'F_CORE.DAT' 15 | outfolder = sys.argv[2] if len(sys.argv) > 2 else 'out' 16 | keyfilename = sys.argv[3] if len(sys.argv) > 3 else 'key.bin' 17 | 18 | # load our key (might be different for different models?) 19 | keybytes = array.array('B') 20 | keybytes.fromfile(open(keyfilename, 'rb'), 256) 21 | 22 | f = open(infilename, 'rb') 23 | 24 | data = f.read(0x200000) 25 | dataout = array.array('B') 26 | 27 | for b in data: 28 | b = struct.unpack('B', b)[0] 29 | dataout.append(keybytes[b]) 30 | 31 | output = open('out/1.nds', 'wb') 32 | output.write(dataout) 33 | output.close(); 34 | 35 | output = open('out/2.nds', 'wb') 36 | output.write(f.read(0x200000)) 37 | output.close(); 38 | 39 | output = open('out/3.bin', 'wb') 40 | output.write(f.read(0x200000)) 41 | output.close(); 42 | 43 | f.close(); 44 | -------------------------------------------------------------------------------- /fcore/key.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/fcore/key.bin -------------------------------------------------------------------------------- /files/F_CORE_V410.DAT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/files/F_CORE_V410.DAT -------------------------------------------------------------------------------- /files/F_CORE_V450.DAT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/files/F_CORE_V450.DAT -------------------------------------------------------------------------------- /files/M3GUpdaterPlus_450HW.nds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/files/M3GUpdaterPlus_450HW.nds -------------------------------------------------------------------------------- /files/M3GUpdaterPlus_450HW.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/files/M3GUpdaterPlus_450HW.txt -------------------------------------------------------------------------------- /tools/z003_dump/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/ds_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # TARGET is the name of the output 13 | # BUILD is the directory where object files & intermediate files will be placed 14 | # SOURCES is a list of directories containing source code 15 | # INCLUDES is a list of directories containing extra header files 16 | # MAXMOD_SOUNDBANK contains a directory of music and sound effect files 17 | #--------------------------------------------------------------------------------- 18 | TARGET := $(shell basename $(CURDIR)) 19 | BUILD := build 20 | SOURCES := source 21 | DATA := data 22 | INCLUDES := include 23 | 24 | #--------------------------------------------------------------------------------- 25 | # options for code generation 26 | #--------------------------------------------------------------------------------- 27 | ARCH := -mthumb -mthumb-interwork 28 | 29 | CFLAGS := -g -Wall -O2\ 30 | -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ 31 | -ffast-math \ 32 | $(ARCH) 33 | 34 | CFLAGS += $(INCLUDE) -DARM9 35 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 36 | 37 | ASFLAGS := -g $(ARCH) 38 | LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 39 | 40 | #--------------------------------------------------------------------------------- 41 | # any extra libraries we wish to link with the project (order is important) 42 | #--------------------------------------------------------------------------------- 43 | LIBS := -lfat -lnds9 44 | 45 | 46 | #--------------------------------------------------------------------------------- 47 | # list of directories containing libraries, this must be the top level containing 48 | # include and lib 49 | #--------------------------------------------------------------------------------- 50 | LIBDIRS := $(LIBNDS) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # no real need to edit anything past this point unless you need to add additional 54 | # rules for different file extensions 55 | #--------------------------------------------------------------------------------- 56 | ifneq ($(BUILD),$(notdir $(CURDIR))) 57 | #--------------------------------------------------------------------------------- 58 | 59 | export ROOTDIR := $(CURDIR) 60 | export OUTPUT := $(CURDIR)/$(TARGET) 61 | 62 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 63 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 64 | 65 | export DEPSDIR := $(CURDIR)/$(BUILD) 66 | 67 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 68 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 69 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 70 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 71 | 72 | #--------------------------------------------------------------------------------- 73 | # use CXX for linking C++ projects, CC for standard C 74 | #--------------------------------------------------------------------------------- 75 | ifeq ($(strip $(CPPFILES)),) 76 | #--------------------------------------------------------------------------------- 77 | export LD := $(CC) 78 | #--------------------------------------------------------------------------------- 79 | else 80 | #--------------------------------------------------------------------------------- 81 | export LD := $(CXX) 82 | #--------------------------------------------------------------------------------- 83 | endif 84 | #--------------------------------------------------------------------------------- 85 | 86 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 87 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 88 | 89 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 90 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 91 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 92 | -I$(CURDIR)/$(BUILD) 93 | 94 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 95 | 96 | .PHONY: $(BUILD) clean 97 | 98 | #--------------------------------------------------------------------------------- 99 | $(BUILD): 100 | @[ -d $@ ] || mkdir -p $@ 101 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 102 | 103 | #--------------------------------------------------------------------------------- 104 | clean: 105 | @echo clean ... 106 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds 107 | 108 | #--------------------------------------------------------------------------------- 109 | else 110 | 111 | #--------------------------------------------------------------------------------- 112 | # main targets 113 | #--------------------------------------------------------------------------------- 114 | $(OUTPUT).nds : $(OUTPUT).elf 115 | $(OUTPUT).elf : $(OFILES) 116 | 117 | $(OUTPUT).nds: $(OUTPUT).elf 118 | ndstool -c $@ -b $(GAME_ICON) "z003dump;" -9 $(OUTPUT).elf 119 | @echo built PROPERLY ... $(notdir $@) 120 | 121 | #--------------------------------------------------------------------------------- 122 | %.bin.o : %.bin 123 | #--------------------------------------------------------------------------------- 124 | @echo $(notdir $<) 125 | $(bin2o) 126 | 127 | -include $(DEPSDIR)/*.d 128 | 129 | #--------------------------------------------------------------------------------------- 130 | endif 131 | #--------------------------------------------------------------------------------------- 132 | -------------------------------------------------------------------------------- /tools/z003_dump/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void waitButtonA() { 8 | while(1) { 9 | scanKeys(); 10 | swiWaitForVBlank(); 11 | if (keysDown() & KEY_A) break; 12 | } 13 | } 14 | 15 | void ioM3CardWaitReady(u32 flags, u8 *command) 16 | { 17 | bool ready = false; 18 | 19 | do { 20 | cardWriteCommand(command); 21 | REG_ROMCTRL = flags; 22 | do { 23 | if (REG_ROMCTRL & CARD_DATA_READY) 24 | if (!CARD_DATA_RD) ready = true; 25 | } while (REG_ROMCTRL & CARD_BUSY); 26 | } while (!ready); 27 | } 28 | 29 | void read_card(u32 address, u32 *destination, u32 length, u8 type) 30 | { 31 | u8 command[8]; 32 | 33 | command[7] = 0xC9; 34 | command[6] = (address >> 24) & 0xff; 35 | command[5] = (address >> 16) & 0xff; 36 | command[4] = (address >> 8) & 0xff; 37 | command[3] = address & 0xff; 38 | command[2] = type; // SW 39 | command[1] = 0; 40 | command[0] = 0; 41 | ioM3CardWaitReady(0xa7586000, command); 42 | 43 | command[7] = 0xCA; 44 | cardPolledTransfer(0xa1586000, destination, length, command); 45 | } 46 | 47 | u16 setup_card() 48 | { 49 | u8 cmdb8[8] = {0, 0, 0, 0, 0, 0, 0, 0xb8}; 50 | u8 cmdb4[8] = {0, 0, 0, 0x0a, 0xa0, 0x55, 0xaa, 0xb4}; 51 | u8 cmdb0[8] = {0, 0, 0, 0, 0, 0, 0, 0xb0}; 52 | u32 ret; 53 | 54 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb8); 55 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 56 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 57 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb0); 58 | 59 | return (u16)ret; 60 | } 61 | 62 | void dump(u8 type, u32 offset, u32 blocks, char* filename) 63 | { 64 | u8 *buffer = (u8*) malloc(blocks * 0x200); 65 | u32 *u32_buffer = (u32*)buffer; // i am bad at pointers 66 | 67 | iprintf("dumping type: %02X\n@%08lX length: %08lX\n", type, offset, blocks * 0x200); 68 | 69 | for (int block = 0; block < blocks; block++) 70 | { 71 | read_card(offset, u32_buffer, 0x80, type); 72 | offset += 0x200; 73 | u32_buffer += 0x80; 74 | } 75 | 76 | for(int y=0; y<8; y++) 77 | { 78 | for (int x=0; x<8; x++) 79 | iprintf("%02x ", buffer[y*8 + x]); 80 | for (int x=0; x<8; x++) 81 | if (buffer[y*8 + x] >= 32 && buffer[y*8 + x] <= 127) 82 | iprintf("%c", buffer[y*8 + x]); 83 | else 84 | iprintf("."); 85 | } 86 | 87 | iprintf("done, writing to file.."); 88 | 89 | FILE* fp = fopen(filename, "wb"); 90 | fwrite(buffer, 0x200, blocks, fp); 91 | fclose(fp); 92 | 93 | free(buffer); 94 | 95 | iprintf("done.\n\n"); 96 | } 97 | 98 | int main(void) { 99 | consoleDemoInit(); 100 | sysSetBusOwners(true, true); 101 | 102 | if(!fatInitDefault()) 103 | { 104 | iprintf("fatInitDefault failed\n"); 105 | return 0; 106 | } 107 | 108 | iprintf("m3i gmp-z003 dumper\n"); 109 | 110 | u16 cardInfo = setup_card(); 111 | iprintf("card Type: %04X\n", cardInfo); 112 | 113 | if (cardInfo != 0x5AA5) 114 | { 115 | iprintf("unsupported, expected 0x5AA5 press A to continue anyway\n"); 116 | waitButtonA(); 117 | //return 0; 118 | } 119 | 120 | iprintf("press A to begin dumping\n"); 121 | waitButtonA(); 122 | 123 | dump(0xF0, 0x0, 0x1000, "dump_f0.bin"); 124 | dump(0xA0, 0x0, 0x80, "dump_a0.bin"); 125 | 126 | waitButtonA(); 127 | 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /tools/z003_flash/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/ds_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # TARGET is the name of the output 13 | # BUILD is the directory where object files & intermediate files will be placed 14 | # SOURCES is a list of directories containing source code 15 | # INCLUDES is a list of directories containing extra header files 16 | # MAXMOD_SOUNDBANK contains a directory of music and sound effect files 17 | #--------------------------------------------------------------------------------- 18 | TARGET := $(shell basename $(CURDIR)) 19 | BUILD := build 20 | SOURCES := source 21 | DATA := data 22 | INCLUDES := include 23 | 24 | #--------------------------------------------------------------------------------- 25 | # options for code generation 26 | #--------------------------------------------------------------------------------- 27 | ARCH := -mthumb -mthumb-interwork 28 | 29 | CFLAGS := -g -Wall -O2\ 30 | -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ 31 | -ffast-math \ 32 | $(ARCH) 33 | 34 | CFLAGS += $(INCLUDE) -DARM9 35 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 36 | 37 | ASFLAGS := -g $(ARCH) 38 | LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 39 | 40 | #--------------------------------------------------------------------------------- 41 | # any extra libraries we wish to link with the project (order is important) 42 | #--------------------------------------------------------------------------------- 43 | LIBS := -lfat -lnds9 44 | 45 | 46 | #--------------------------------------------------------------------------------- 47 | # list of directories containing libraries, this must be the top level containing 48 | # include and lib 49 | #--------------------------------------------------------------------------------- 50 | LIBDIRS := $(LIBNDS) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # no real need to edit anything past this point unless you need to add additional 54 | # rules for different file extensions 55 | #--------------------------------------------------------------------------------- 56 | ifneq ($(BUILD),$(notdir $(CURDIR))) 57 | #--------------------------------------------------------------------------------- 58 | 59 | export ROOTDIR := $(CURDIR) 60 | export OUTPUT := $(CURDIR)/$(TARGET) 61 | 62 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 63 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 64 | 65 | export DEPSDIR := $(CURDIR)/$(BUILD) 66 | 67 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 68 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 69 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 70 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 71 | 72 | #--------------------------------------------------------------------------------- 73 | # use CXX for linking C++ projects, CC for standard C 74 | #--------------------------------------------------------------------------------- 75 | ifeq ($(strip $(CPPFILES)),) 76 | #--------------------------------------------------------------------------------- 77 | export LD := $(CC) 78 | #--------------------------------------------------------------------------------- 79 | else 80 | #--------------------------------------------------------------------------------- 81 | export LD := $(CXX) 82 | #--------------------------------------------------------------------------------- 83 | endif 84 | #--------------------------------------------------------------------------------- 85 | 86 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 87 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 88 | 89 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 90 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 91 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 92 | -I$(CURDIR)/$(BUILD) 93 | 94 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 95 | 96 | .PHONY: $(BUILD) clean 97 | 98 | #--------------------------------------------------------------------------------- 99 | $(BUILD): 100 | @[ -d $@ ] || mkdir -p $@ 101 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 102 | 103 | #--------------------------------------------------------------------------------- 104 | clean: 105 | @echo clean ... 106 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds 107 | 108 | #--------------------------------------------------------------------------------- 109 | else 110 | 111 | #--------------------------------------------------------------------------------- 112 | # main targets 113 | #--------------------------------------------------------------------------------- 114 | $(OUTPUT).nds : $(OUTPUT).elf 115 | $(OUTPUT).elf : $(OFILES) 116 | 117 | $(OUTPUT).nds: $(OUTPUT).elf 118 | ndstool -c $@ -b $(GAME_ICON) "z003dump;" -9 $(OUTPUT).elf 119 | @echo built PROPERLY ... $(notdir $@) 120 | 121 | #--------------------------------------------------------------------------------- 122 | %.bin.o : %.bin 123 | #--------------------------------------------------------------------------------- 124 | @echo $(notdir $<) 125 | $(bin2o) 126 | 127 | -include $(DEPSDIR)/*.d 128 | 129 | #--------------------------------------------------------------------------------------- 130 | endif 131 | #--------------------------------------------------------------------------------------- 132 | -------------------------------------------------------------------------------- /tools/z003_flash/source/cart_commands.c: -------------------------------------------------------------------------------- 1 | #include "cart_commands.h" 2 | 3 | void m3_card_wait_ready(u32 flags, u8 *command) 4 | { 5 | bool ready = false; 6 | 7 | do { 8 | cardWriteCommand(command); 9 | REG_ROMCTRL = flags; 10 | do { 11 | if (REG_ROMCTRL & CARD_DATA_READY) 12 | if (!CARD_DATA_RD) ready = true; 13 | } while (REG_ROMCTRL & CARD_BUSY); 14 | } while (!ready); 15 | } 16 | 17 | void read_card(u32 address, u32 *destination, u32 length, u8 type) 18 | { 19 | u8 command[8]; 20 | 21 | command[7] = 0xC9; 22 | command[6] = (address >> 24) & 0xff; 23 | command[5] = (address >> 16) & 0xff; 24 | command[4] = (address >> 8) & 0xff; 25 | command[3] = address & 0xff; 26 | command[2] = type; // SW 27 | command[1] = 0; 28 | command[0] = 0; 29 | m3_card_wait_ready(0xa7586000, command); 30 | 31 | command[7] = 0xCA; 32 | cardPolledTransfer(0xa1586000, destination, length, command); 33 | } 34 | 35 | void write_card(u32 address, u32 *source, u32 length, u8 type) 36 | { 37 | u8 command[8]; 38 | u32 data = 0; 39 | 40 | command[7] = 0xC5; // GMP-Z003 41 | command[6] = (address >> 24) & 0xff; 42 | command[5] = (address >> 16) & 0xff; 43 | command[4] = (address >> 8) & 0xff; 44 | command[3] = address & 0xff; 45 | command[2] = type; 46 | command[1] = 0; 47 | command[0] = 0; 48 | cardWriteCommand(command); 49 | REG_ROMCTRL = 0xe1586000; 50 | u32 * target = source + length; 51 | do { 52 | // Write data if ready 53 | if (REG_ROMCTRL & CARD_DATA_READY) { 54 | if (source < target) { 55 | if ((u32)source & 0x03) 56 | data = ((uint8*)source)[0] | (((uint8*)source)[1] << 8) | (((uint8*)source)[2] << 16) | (((uint8*)source)[3] << 24); 57 | else 58 | data = *source; 59 | } 60 | source++; 61 | CARD_DATA_RD = data; 62 | } 63 | } while (REG_ROMCTRL & CARD_BUSY); 64 | command[7] = 0xC6; // GMP-Z003 65 | m3_card_wait_ready(0xa7586000, command); 66 | } 67 | 68 | u16 setup_card() 69 | { 70 | u8 cmdb8[8] = {0, 0, 0, 0, 0, 0, 0, 0xb8}; 71 | u8 cmdb4[8] = {0, 0, 0, 0x0a, 0xa0, 0x55, 0xaa, 0xb4}; 72 | u8 cmdb0[8] = {0, 0, 0, 0, 0, 0, 0, 0xb0}; 73 | u32 ret; 74 | 75 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb8); 76 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 77 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 78 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb0); 79 | // repeat the same commands again - puts it in a known state :s 80 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb8); 81 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 82 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 83 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb0); 84 | 85 | return (u16)ret; 86 | } 87 | 88 | void read_blocks(u8 type, u32 offset, u8 *buffer, u32 blocks) 89 | { 90 | u32 *u32_buffer = (u32*)buffer; // i am bad at pointers 91 | 92 | for (int block = 0; block < blocks; block++) 93 | { 94 | read_card(offset, u32_buffer, 0x80, type); 95 | offset += 0x200; 96 | u32_buffer += 0x80; 97 | } 98 | } -------------------------------------------------------------------------------- /tools/z003_flash/source/cart_commands.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | void m3_card_wait_ready(u32 flags, u8 *command); 7 | void read_card(u32 address, u32 *destination, u32 length, u8 type); 8 | void write_card(u32 address, u32 *source, u32 length, u8 type); 9 | u16 setup_card(); 10 | void read_blocks(u8 type, u32 offset, u8 *buffer, u32 blocks); -------------------------------------------------------------------------------- /tools/z003_flash/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "cart_commands.h" 8 | 9 | void waitButtonA() { 10 | while(1) { 11 | scanKeys(); 12 | swiWaitForVBlank(); 13 | if (keysDown() & KEY_A) break; 14 | } 15 | } 16 | 17 | int main(void) { 18 | consoleDemoInit(); 19 | sysSetBusOwners(true, true); 20 | 21 | if(!fatInitDefault()) 22 | { 23 | iprintf("Failed to initalize fat device.\n"); 24 | return 0; 25 | } 26 | 27 | iprintf("M3i GMP-Z003 flasher\n"); 28 | 29 | u16 cardInfo = setup_card(); 30 | iprintf("cardcmdb0: %04X\n", cardInfo); 31 | 32 | if (cardInfo != 0x5AA5) 33 | { 34 | iprintf("error, expected 0x5AA5\n"); 35 | iprintf("your card is incompatible - press A to exit\n"); 36 | waitButtonA(); 37 | return 0; 38 | } 39 | 40 | iprintf("warning: probably gonna brick your cart\n\n"); 41 | 42 | iprintf("press A to continue, press B to exit\n\n"); 43 | while(1) { 44 | scanKeys(); 45 | swiWaitForVBlank(); 46 | if (keysDown() & KEY_A) break; 47 | if (keysDown() & KEY_B) return 0; 48 | } 49 | 50 | FILE *fp = fopen("flash.bin", "rb"); 51 | if (fp == NULL) 52 | { 53 | iprintf("could not find flash.bin\n"); 54 | waitButtonA(); 55 | return 0; 56 | } 57 | u8 *flash = (u8*)malloc(0x200 * 0x1000); 58 | fread(flash, 1, 0x200 * 0x1000, fp); 59 | fclose(fp); 60 | 61 | iprintf("erasing flash "); 62 | 63 | // erase it all 64 | for (int i = 0; i < 0x200; i++) 65 | { 66 | iprintf("\rerasing flash %d / %d", i+1, 0x200); 67 | write_card(i * 0x10000, 0, 0x200, 0xE0); 68 | } 69 | 70 | iprintf("\nwriting flash "); 71 | 72 | u32 *write_buffer = (u32*)flash; 73 | u32 blocks = 0x1000; 74 | for (int block = 0; block < blocks; block++) 75 | { 76 | iprintf("\rwriting flash %d / %ld", block+1, blocks); 77 | 78 | write_card(block * 0x200, write_buffer, 0x80, 0xF0); 79 | write_buffer += 0x80; 80 | } 81 | 82 | free(flash); 83 | 84 | iprintf("\n\nflash complete\n"); 85 | waitButtonA(); 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /tools/z003_ntrboot/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/ds_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # TARGET is the name of the output 13 | # BUILD is the directory where object files & intermediate files will be placed 14 | # SOURCES is a list of directories containing source code 15 | # INCLUDES is a list of directories containing extra header files 16 | # MAXMOD_SOUNDBANK contains a directory of music and sound effect files 17 | #--------------------------------------------------------------------------------- 18 | TARGET := $(shell basename $(CURDIR)) 19 | BUILD := build 20 | SOURCES := source 21 | DATA := data 22 | INCLUDES := include 23 | 24 | #--------------------------------------------------------------------------------- 25 | # options for code generation 26 | #--------------------------------------------------------------------------------- 27 | ARCH := -mthumb -mthumb-interwork 28 | 29 | CFLAGS := -g -Wall -O2\ 30 | -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ 31 | -ffast-math \ 32 | $(ARCH) 33 | 34 | CFLAGS += $(INCLUDE) -DARM9 35 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 36 | 37 | ASFLAGS := -g $(ARCH) 38 | LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 39 | 40 | #--------------------------------------------------------------------------------- 41 | # any extra libraries we wish to link with the project (order is important) 42 | #--------------------------------------------------------------------------------- 43 | LIBS := -lfat -lnds9 44 | 45 | 46 | #--------------------------------------------------------------------------------- 47 | # list of directories containing libraries, this must be the top level containing 48 | # include and lib 49 | #--------------------------------------------------------------------------------- 50 | LIBDIRS := $(LIBNDS) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # no real need to edit anything past this point unless you need to add additional 54 | # rules for different file extensions 55 | #--------------------------------------------------------------------------------- 56 | ifneq ($(BUILD),$(notdir $(CURDIR))) 57 | #--------------------------------------------------------------------------------- 58 | 59 | export ROOTDIR := $(CURDIR) 60 | export OUTPUT := $(CURDIR)/$(TARGET) 61 | 62 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 63 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 64 | 65 | export DEPSDIR := $(CURDIR)/$(BUILD) 66 | 67 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 68 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 69 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 70 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 71 | 72 | #--------------------------------------------------------------------------------- 73 | # use CXX for linking C++ projects, CC for standard C 74 | #--------------------------------------------------------------------------------- 75 | ifeq ($(strip $(CPPFILES)),) 76 | #--------------------------------------------------------------------------------- 77 | export LD := $(CC) 78 | #--------------------------------------------------------------------------------- 79 | else 80 | #--------------------------------------------------------------------------------- 81 | export LD := $(CXX) 82 | #--------------------------------------------------------------------------------- 83 | endif 84 | #--------------------------------------------------------------------------------- 85 | 86 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 87 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 88 | 89 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 90 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 91 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 92 | -I$(CURDIR)/$(BUILD) 93 | 94 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 95 | 96 | .PHONY: $(BUILD) clean 97 | 98 | #--------------------------------------------------------------------------------- 99 | $(BUILD): 100 | @[ -d $@ ] || mkdir -p $@ 101 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 102 | 103 | #--------------------------------------------------------------------------------- 104 | clean: 105 | @echo clean ... 106 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds 107 | 108 | #--------------------------------------------------------------------------------- 109 | else 110 | 111 | #--------------------------------------------------------------------------------- 112 | # main targets 113 | #--------------------------------------------------------------------------------- 114 | $(OUTPUT).nds : $(OUTPUT).elf 115 | $(OUTPUT).elf : $(OFILES) 116 | 117 | $(OUTPUT).nds: $(OUTPUT).elf 118 | ndstool -c $(OUTPUT)_ds.nds -9 $(OUTPUT).elf -h 0x200 119 | ndstool -c $(OUTPUT)_dsi.nds -9 $(OUTPUT).elf 120 | 121 | #--------------------------------------------------------------------------------- 122 | %.bin.o : %.bin 123 | #--------------------------------------------------------------------------------- 124 | @echo $(notdir $<) 125 | $(bin2o) 126 | 127 | -include $(DEPSDIR)/*.d 128 | 129 | #--------------------------------------------------------------------------------------- 130 | endif 131 | #--------------------------------------------------------------------------------------- 132 | -------------------------------------------------------------------------------- /tools/z003_ntrboot/README.md: -------------------------------------------------------------------------------- 1 | # M3i GMP-Z003 NTRBoot Injector 2 | 3 | ## Synopsis 4 | 5 | A tool to flash bootrom hacks onto your M3i GMP-Z003 (no the older model will not work with this) 6 | You can use this if you can't use [ntrboot_flasher](https://github.com/kitling/ntrboot_flasher) 7 | 8 | If you don't know what you're doing, stop. 9 | 10 | ![injecting ntrboot](screenshot.jpg) 11 | 12 | ## Usage 13 | 14 | **Make sure your M3i Zero is flashed to either 4.1 or 4.2. Version 4.5 will not work.** 15 | The game cart should read `Deep Labyrinth` or `Rafa Nadal Tennis`. 16 | 17 | If you already have a hacked 3DS you can do either of these: 18 | 19 | * Use [ntrboot_flasher](https://github.com/kitling/ntrboot_flasher) 20 | * Use `z003_ntrboot_dsi.nds` from the [hb-menu](https://github.com/devkitPro/nds-hb-menu) application. 21 | 22 | If you have a DS device that will boot the flashcart (doesn't have to be hacked) then you can: 23 | 24 | * Use `z003_ntrboot_ds.nds` from M3 Sakura. 25 | 26 | When using `z003_ntrboot_ds(i).nds` ensure you have the **NTR** FIRM payload you want in the file: 27 | `inject_ntr.firm` next to the NDS file on the SD card (and also the root just to be sure.) 28 | 29 | Backups are stored in: `flash_backup.nds` 30 | 31 | ## Downloads 32 | 33 | You can download precompiled binaries of `z003_ntrboot_ds(i).nds` from the releases section. 34 | 35 | ## Credits 36 | 37 | TuxSH, WinterMute and NormMatt for putting up with me asking dumb shit in #Cakey -------------------------------------------------------------------------------- /tools/z003_ntrboot/data/blowfish_retail.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/tools/z003_ntrboot/data/blowfish_retail.bin -------------------------------------------------------------------------------- /tools/z003_ntrboot/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/handsomematt/gmp-z003/d92492a5ec379ea2b5843959cb68144edf5f34c4/tools/z003_ntrboot/screenshot.jpg -------------------------------------------------------------------------------- /tools/z003_ntrboot/source/cart_commands.c: -------------------------------------------------------------------------------- 1 | #include "cart_commands.h" 2 | 3 | void m3_card_wait_ready(u32 flags, u8 *command) 4 | { 5 | bool ready = false; 6 | 7 | do { 8 | cardWriteCommand(command); 9 | REG_ROMCTRL = flags; 10 | do { 11 | if (REG_ROMCTRL & CARD_DATA_READY) 12 | if (!CARD_DATA_RD) ready = true; 13 | } while (REG_ROMCTRL & CARD_BUSY); 14 | } while (!ready); 15 | } 16 | 17 | void read_card(u32 address, u32 *destination, u32 length, u8 type) 18 | { 19 | u8 command[8]; 20 | 21 | command[7] = 0xC9; 22 | command[6] = (address >> 24) & 0xff; 23 | command[5] = (address >> 16) & 0xff; 24 | command[4] = (address >> 8) & 0xff; 25 | command[3] = address & 0xff; 26 | command[2] = type; // SW 27 | command[1] = 0; 28 | command[0] = 0; 29 | m3_card_wait_ready(0xa7586000, command); 30 | 31 | command[7] = 0xCA; 32 | cardPolledTransfer(0xa1586000, destination, length, command); 33 | } 34 | 35 | void write_card(u32 address, u32 *source, u32 length, u8 type) 36 | { 37 | u8 command[8]; 38 | u32 data = 0; 39 | 40 | command[7] = 0xC5; // GMP-Z003 41 | command[6] = (address >> 24) & 0xff; 42 | command[5] = (address >> 16) & 0xff; 43 | command[4] = (address >> 8) & 0xff; 44 | command[3] = address & 0xff; 45 | command[2] = type; 46 | command[1] = 0; 47 | command[0] = 0; 48 | cardWriteCommand(command); 49 | REG_ROMCTRL = 0xe1586000; 50 | u32 * target = source + length; 51 | do { 52 | // Write data if ready 53 | if (REG_ROMCTRL & CARD_DATA_READY) { 54 | if (source < target) { 55 | if ((u32)source & 0x03) 56 | data = ((uint8*)source)[0] | (((uint8*)source)[1] << 8) | (((uint8*)source)[2] << 16) | (((uint8*)source)[3] << 24); 57 | else 58 | data = *source; 59 | } 60 | source++; 61 | CARD_DATA_RD = data; 62 | } 63 | } while (REG_ROMCTRL & CARD_BUSY); 64 | command[7] = 0xC6; // GMP-Z003 65 | m3_card_wait_ready(0xa7586000, command); 66 | } 67 | 68 | u16 setup_card() 69 | { 70 | u8 cmdb8[8] = {0, 0, 0, 0, 0, 0, 0, 0xb8}; 71 | u8 cmdb4[8] = {0, 0, 0, 0x0a, 0xa0, 0x55, 0xaa, 0xb4}; 72 | u8 cmdb0[8] = {0, 0, 0, 0, 0, 0, 0, 0xb0}; 73 | u32 ret; 74 | 75 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb8); 76 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 77 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 78 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb0); 79 | // repeat the same commands again - puts it in a known state :s 80 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb8); 81 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 82 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb4); 83 | cardPolledTransfer(0xa7586000, &ret, 1, cmdb0); 84 | 85 | return (u16)ret; 86 | } 87 | 88 | void read_blocks(u8 type, u32 offset, u8 *buffer, u32 blocks) 89 | { 90 | u32 *u32_buffer = (u32*)buffer; // i am bad at pointers 91 | 92 | for (int block = 0; block < blocks; block++) 93 | { 94 | read_card(offset, u32_buffer, 0x80, type); 95 | offset += 0x200; 96 | u32_buffer += 0x80; 97 | } 98 | } -------------------------------------------------------------------------------- /tools/z003_ntrboot/source/cart_commands.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | void m3_card_wait_ready(u32 flags, u8 *command); 7 | void read_card(u32 address, u32 *destination, u32 length, u8 type); 8 | void write_card(u32 address, u32 *source, u32 length, u8 type); 9 | u16 setup_card(); 10 | void read_blocks(u8 type, u32 offset, u8 *buffer, u32 blocks); -------------------------------------------------------------------------------- /tools/z003_ntrboot/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "cart_commands.h" 8 | #include "blowfish_retail_bin.h" 9 | 10 | #define FILENAME_FIRM "inject_ntr.firm" 11 | #define FILENAME_FLASH_BACKUP "flash_backup.nds" 12 | 13 | void waitButtonA() { 14 | while(1) { 15 | scanKeys(); 16 | swiWaitForVBlank(); 17 | if (keysDown() & KEY_A) break; 18 | } 19 | } 20 | 21 | 22 | void display_hex(u8 *buffer, int lines) 23 | { 24 | for (int y=0; y= 32 && buffer[y*8 + x] <= 127) 30 | iprintf("%c", buffer[y*8 + x]); 31 | else 32 | iprintf("."); 33 | } 34 | } 35 | 36 | int main(void) { 37 | consoleDemoInit(); 38 | sysSetBusOwners(true, true); 39 | 40 | if(!fatInitDefault()) 41 | { 42 | iprintf("Failed to initalize fat device.\n"); 43 | return 0; 44 | } 45 | 46 | iprintf("M3i GMP-Z003 ntrboot injector\n"); 47 | 48 | u16 cardInfo = setup_card(); 49 | iprintf("cardcmdb0: %04X\n", cardInfo); 50 | 51 | if (cardInfo != 0x5AA5) 52 | { 53 | iprintf("error, expected 0x5AA5\n"); 54 | iprintf("your card is incompatible - press A to exit\n"); 55 | waitButtonA(); 56 | return 0; 57 | } 58 | 59 | iprintf("warning: your device will become unusable as a flashcart until you reflash it back\n\n"); 60 | 61 | iprintf("press A to continue, press B to exit\n\n"); 62 | while(1) { 63 | scanKeys(); 64 | swiWaitForVBlank(); 65 | if (keysDown() & KEY_A) break; 66 | if (keysDown() & KEY_B) return 0; 67 | } 68 | 69 | iprintf("reading flash...\n\n"); 70 | 71 | u8 *flash_buffer = (u8*) malloc(0x200 * 0x1000); 72 | read_blocks(0xF0, 0, flash_buffer, 0x1000); 73 | display_hex(flash_buffer, 4); 74 | 75 | iprintf("backing up to file %s... ", FILENAME_FLASH_BACKUP); 76 | 77 | FILE* fp = fopen(FILENAME_FLASH_BACKUP, "wb"); 78 | fwrite(flash_buffer, 0x200, 0x1000, fp); 79 | fclose(fp); 80 | 81 | iprintf("done\n"); 82 | 83 | iprintf("reading ntr firm file... "); 84 | fp = fopen(FILENAME_FIRM,"rb"); 85 | if (fp == NULL) 86 | { 87 | iprintf("\ncould not find %s\n", FILENAME_FIRM); 88 | waitButtonA(); 89 | return 0; 90 | } 91 | 92 | fseek(fp, 0, SEEK_END); 93 | u32 firm_size = ftell(fp); 94 | u8 *firm = (u8*)malloc(firm_size); 95 | 96 | fseek(fp, 0, SEEK_SET); 97 | fread(firm, 1, firm_size, fp); 98 | fclose(fp); 99 | 100 | iprintf("done\n\n"); 101 | 102 | iprintf("injecting ntrboot\n\n"); 103 | 104 | memcpy(flash_buffer + 0x1000, (u8*)blowfish_retail_bin+0x48, 0x1000); 105 | memcpy(flash_buffer + 0x2000, (u8*)blowfish_retail_bin, 0x48); 106 | 107 | memcpy(flash_buffer + 0x7E00, firm, firm_size); 108 | 109 | iprintf("erasing flash "); 110 | 111 | // erase it all 112 | for (int i = 0; i < 0x200; i++) 113 | { 114 | iprintf("\rerasing flash %d / %d", i+1, 0x200); 115 | write_card(i * 0x10000, 0, 0x200, 0xE0); 116 | } 117 | 118 | iprintf("\nwriting flash "); 119 | 120 | u32 *write_buffer = (u32*)flash_buffer; 121 | u32 blocks = 0x1000; 122 | for (int block = 0; block < blocks; block++) 123 | { 124 | iprintf("\rwriting flash %d / %ld", block+1, blocks); 125 | 126 | write_card(block * 0x200, write_buffer, 0x80, 0xF0); 127 | write_buffer += 0x80; 128 | } 129 | 130 | free(flash_buffer); 131 | 132 | iprintf("\n\ninjection complete\n"); 133 | waitButtonA(); 134 | 135 | return 0; 136 | } 137 | --------------------------------------------------------------------------------