├── 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 |
9 |
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 | 
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 |
--------------------------------------------------------------------------------