Blame | Last modification | View Log | RSS feed
@@@ emBIOS Loader for iPod Nano 2G@@ Copyright 2010 TheSeven@@@ This file is part of emBIOS.@@ emBIOS is free software: you can redistribute it and/or@ modify it under the terms of the GNU General Public License as@ published by the Free Software Foundation, either version 2 of the@ License, or (at your option) any later version.@@ emBIOS is distributed in the hope that it will be useful,@ but WITHOUT ANY WARRANTY; without even the implied warranty of@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.@ See the GNU General Public License for more details.@@ You should have received a copy of the GNU General Public License along@ with emBIOS. If not, see <http://www.gnu.org/licenses/>.@@#include "build/version.h".global _start_start:msr cpsr_c, #0xd3mrc p15, 0, r0,c1,c0bic r0, r0, #1mcr p15, 0, r0,c1,c0mov r0, #0mcr p15, 0, r0,c7,c5adr lr, cacheflush_doneflushcache:mov r0, #0flushcache_loop:mcr p15, 0, r0,c7,c14,2add r10, r0, #0x10mcr p15, 0, r10,c7,c14,2add r10, r10, #0x10mcr p15, 0, r10,c7,c14,2add r10, r10, #0x10mcr p15, 0, r10,c7,c14,2adds r0, r0, #0x04000000bne flushcache_loopmcr p15, 0, r0,c7,c10,4mov pc, lrcacheflush_done:adr lr, values1ldmia lr!, {r0-r13}str r1, [r0,#0x88]str r2, [r0,#0xf0]str r4, [r3,#0x38]mov r1, #0str r7, [r0]str r1, [r0,#0x04]str r8, [r0,#0x10]str r1, [r0,#0x14]str r9, [r0,#0x20]str r1, [r0,#0x24]str r10, [r0,#0x30]str r1, [r0,#0x34]str r9, [r0,#0x40]str r1, [r0,#0x44]str r11, [r0,#0x50]str r1, [r0,#0x54]str r12, [r0,#0x60]str r1, [r0,#0x64]str r13, [r0,#0xa0]str r1, [r0,#0xa4]str r5, [r0,#0xb0]mov r3, #1str r3, [r0,#0xb4]str r6, [r0,#0xc0]ldmia lr, {r4-r14}str r1, [r0,#0xc4]str r6, [r0,#0xd0]str r1, [r0,#0xd4]str r6, [r0,#0xe0]str r1, [r0,#0xe4]str r7, [r0,#0xf0]str r1, [r0,#0xf4]ldr r3, [r8,#0x24]orr r3, r3, #3str r3, [r8,#0x24]ldr r3, [r8,#0x28]bic r3, r3, #0x4000str r3, [r8,#0x28]mov r3, #0x3C400000str r1, [r3]str r12, [r8,#0x0c]ldr r3, [r8,#0x24]orr r3, r3, #0x54str r3, [r8,#0x24]mov r3, #0x2000waitpll1:subs r3, r3, #1bne waitpll1ldr r3, [r8]bic r3, r3, r5orr r3, r3, r4str r3, [r8]ldr r3, [r8,#0x24]bic r3, r3, #1str r3, [r8,#0x24]mov r3, #0x84str r3, [r0,#0x68]str r13, [r8,#0x04]mov r3, #0xa000waitpll2:subs r3, r3, #1bne waitpll2ldr r3, [r8,#0x24]orr r3, r3, #1str r3, [r8,#0x24]mov r3, #0x6000waitpll3:subs r3, r3, #1bne waitpll3ldr r3, [r8]bic r3, r3, r9orr r3, r3, r10str r3, [r8]ldr r3, [r8,#0x3c]bic r3, r3, #0x400orr r3, r3, #0x280str r3, [r8,#0x3c]ldr r3, [r8,#0x10]bic r3, r3, #0x1f8orr r3, r3, #0x37str r3, [r8,#0x10]mrc p15, 0, r3,c1,c0orr r3, r3, #0xc0000000mcr p15, 0, r3,c1,c0str r11, [r8,#0x28]str r14, [r8,#0x40]sub r6, r0, #0x00800000mov r5, #0xf700str r5, [r6,#0x88]mov r5, #0x1100orr r5, r5, #0x11str r5, [r0,#0x88]add r4, r6, #0x00200000str r1, [r4,#0x08]mov r5, #0xb7str r5, [r4]mov r5, #0x10str r5, [r4,#0x04]b setuppmupmuinitdata:.byte 3, 0x39, 0x18, 0, 0x8c.byte 3, 0x13, 3, 0, 0.byte 6, 0x16, 7, 0, 5, 2, 0x6b, 0.byte 4, 0x1e, 0x12, 1, 0, 0x10.byte 6, 0x22, 0x2f, 1, 0, 0x10, 9, 1.byte 6, 0x31, 0x15, 1, 0x0f, 3, 0x15, 0.byte 1, 0x43, 0.byte 1, 0x4e, 0.byte 1, 0x58, 0.byte 5, 0x07, 0xb0, 0x0f, 0xfe, 0xfc, 0xff.byte 5, 0x0d, 0xdf, 0xaa, 0x4a, 5, 0x27.byte 0.align 2val_006a49a5:.word 0x006a49a5values1:.word 0x3CF00000 @ R0.word 0x00001111 @ R1.word 0x00000221 @ R2.word 0x38200000 @ R3val_00990999:.word 0x00990999 @ R4.word 0x41001111 @ R5.word 0x11114444 @ R6.word 0x11221111 @ R7.word 0x11001744 @ R8.word 0x33333333 @ R9.word 0x11113333 @ R10.word 0x77721151 @ R11.word 0x12111111 @ R12.word 0x11111000 @ R13.word 0x60007000 @ R4.word 0x7F007F00 @ R5.word 0x44444444 @ R6.word 0x22222221 @ R7.word 0x3C500000 @ R8.word 0xFF00FF00 @ R9.word 0x20803180 @ R10.word 0xFFDFF7CF @ R11.word 0x00061800 @ R12.word 0x00021200 @ R13.word 0xFFFFEF7E @ R14setuppmu:mov sp, pcbl getpowerokbeq poweroffadr r2, pmuinitdatapmuinitloop:ldrb r3, [r2], #1movs r3, r3beq pmuinitdoneldrb r1, [r2], #1mov r0, #0xe6bl i2csendb pmuinitlooppmuinitdone:orr r12, r12, #0x00600000mov r1, #1ldr r0, [r12,#0x100]bic r0, r0, #0x0forr r0, r0, #1str r0, [r12,#0x100]str r1, [r12,#0x10c]sub r11, r12, #0x04d00000ldr r0, [r11,#0x80]bic r0, r0, #0x20000str r0, [r11,#0x80]ldr r0, [r11]bic r0, r0, #0xc00orr r0, r0, #0x500str r0, [r11]mov r0, #3str r0, [r11,#0x04]mov r0, #1bl sleepmsmov r0, #0x200orr r0, r0, #0xedstr r0, [r11,#0x08]ldr r0, val_006a49a5str r0, [r11,#0x10]mov r0, #0x37str r0, [r11,#0x0c]ldr r1, [r11,#0x04]bic r1, r1, #0x700orr r0, r1, #0x200str r0, [r11,#0x04]orr r0, r1, #0x300str r0, [r11,#0x04]str r0, [r11,#0x04]orr r0, r1, #0x100str r0, [r11,#0x04]orr r0, r1, #0x500str r0, [r11,#0x04]ldr r0, [r11,#0x08]orr r0, r0, #0x1000str r0, [r11,#0x08]ldr r0, val_00990999str r0, [r11,#0x38]ldr r0, [r12,#0xf0]bic r0, r0, #0xff000000bic r0, r0, #0x00ff0000orr r0, r0, #0x22000000orr r0, r0, #0x00220000str r0, [r12,#0xf0]mov r0, #0xf0str r0, [r12,#0xfc]sub r10, r12, #0x00d00000ldr r0, [r10]mov r0, r0,lsr#20mov r0, r0,lsl#20str r0, [r10]mov r1, #0x3a000orr r1, r1, #0x980str r1, [r10,#0x08]orr r0, r0, #0x300000str r0, [r10]bl initlcdmov r0, #0x3fmcr p15, 0, r0,c6,c0,1 @ CS0: 4GB at offset 0 - everythingmcr p15, 0, r0,c6,c0,0 @ DS0: 4GB at offset 0 - everythingmov r0, #0x31mcr p15, 0, r0,c6,c1,1 @ CS1: SRAM/SDRAM mirrormcr p15, 0, r0,c6,c1,0 @ DS1: SRAM/SDRAM mirroradd r0, r0, #0x08000000mcr p15, 0, r0,c6,c2,1 @ CS2: SDRAMmcr p15, 0, r0,c6,c2,0 @ DS2: SDRAMmov r0, #0x23add r0, r0, #0x22000000mcr p15, 0, r0,c6,c3,1 @ CS3: SRAMmcr p15, 0, r0,c6,c3,0 @ DS3: SRAMmov r0, #0x27add r0, r0, #0x24000000mcr p15, 0, r0,c6,c4,1 @ CS4: NOR flashmcr p15, 0, r0,c6,c4,0 @ DS4: NOR flashmcr p15, 0, r1,c6,c5,1 @ CS5: unusedmcr p15, 0, r1,c6,c5,0 @ DS5: unusedmcr p15, 0, r1,c6,c6,1 @ CS6: unusedmcr p15, 0, r1,c6,c6,0 @ DS6: unusedmcr p15, 0, r1,c6,c7,1 @ CS7: unusedmcr p15, 0, r1,c6,c7,0 @ DS7: unusedmov r0, #0x1emcr p15, 0, r0,c2,c0, 1 @ CS1-4: cacheablemcr p15, 0, r0,c2,c0, 0 @ DS1-4: cacheablemcr p15, 0, r0,c3,c0, 0 @ DS1-4: write cacheablemov r0, #0x300add r0, r0, #0xffmcr p15, 0, r0,c5,c0, 1 @ CS0-4: full accessmcr p15, 0, r0,c5,c0, 0 @ DS0-4: full accessmrc p15, 0, r0,c1,c0orr r0, r0, #5orr r0, r0, #0x1000mcr p15, 0, r0,c1,c0 @ Re-enable the Protection Unit and cachesmov r11, #0x22000000orr r11, r11, #0x10000mov r0, r11mov r3, #0x2d00orr r3, r3, #0x60sub r2, r1, #1fillbuff:str r2, [r0], #4subs r3, r3, #1bne fillbuffmov r0, r11adr r3, textbl rendertextadd r0, r11, #0xb00bl rendertextadd r0, r11, #0x2100bl rendertextmov r0, #0mov r1, #175mov r2, #0mov r3, #131str r11, [sp]bl displaylcdmov r0, #0xe6mov r1, #0x2bmov r2, #4bl i2csendbytemov r0, #0xe6mov r1, #0x28mov r2, #10bl i2csendbytemov r0, #0xe6mov r1, #0x29mov r2, #1bl i2csendbyteorr r12, r12, #0xcf00000ldr r0, [r12,#0xe4]tst r0, #0x40beq recoverymodeb decompressrendertext:stmfd sp!, {r4-r6,lr}rendertext_next:ldrb r12, [r3], #1cmp r12, #0beq rendertext_donecmn r2, #1beq rendertext_nobgmov r6, r0mov r4, #8rendertext_bgrow:mov r5, #6rendertext_bgcol:cmn r2, #2strneh r2, [r6], #2bne rendertext_noblendldrh lr, [r6]tst lr, #1orrne lr, lr, #0x10000mov lr, lr,lsr#1bic lr, lr, #0x1000bic lr, lr, #0x84strh lr, [r6], #2rendertext_noblend:subs r5, r5, #1bne rendertext_bgcoladd r6, r6, #340subs r4, r4, #1bne rendertext_bgrowrendertext_nobg:adr r5, fontsub r12, r12, #0x20cmp r12, #0x5faddcc r5, r12,lsl#2addcc r5, r12mov r12, #5rendertext_col:mov r6, r0ldrb r4, [r5], #1rendertext_row:tst r4, #1strneh r1, [r6]add r6, r6, #352movs r4, r4,lsr#1bne rendertext_rowadd r0, r0, #2subs r12, r12, #1bne rendertext_coladd r0, r0, #2b rendertext_nextrendertext_done:ldmfd sp!, {r4-r6,pc}text:.ascii "emBIOS Loader v".ascii VERSION.ascii " r".ascii VERSION_SVN.ascii "\0".ascii "Switch HOLD on for recovery\0".ascii "Loading emBIOS...\0"font:.byte 0, 0, 0, 0, 0.byte 0, 0, 95, 0, 0.byte 0, 7, 0, 7, 0.byte 20, 127, 20, 127, 20.byte 36, 42, 127, 42, 18.byte 35, 19, 8, 100, 98.byte 54, 73, 85, 34, 80.byte 5, 3, 0, 0, 0.byte 28, 34, 65, 0, 0.byte 0, 0, 65, 34, 28.byte 20, 8, 62, 8, 20.byte 8, 8, 62, 8, 8.byte 0, -96, 96, 0, 0.byte 8, 8, 8, 8, 8.byte 0, 96, 96, 0, 0.byte 32, 16, 8, 4, 2.byte 62, 81, 73, 69, 62.byte 0, 66, 127, 64, 0.byte 66, 97, 81, 73, 70.byte 33, 65, 69, 75, 49.byte 24, 20, 18, 127, 16.byte 39, 69, 69, 69, 57.byte 60, 74, 73, 73, 48.byte 1, 113, 9, 5, 3.byte 54, 73, 73, 73, 54.byte 6, 73, 73, 41, 30.byte 0, 54, 54, 0, 0.byte 0, 86, 54, 0, 0.byte 8, 20, 34, 65, 0.byte 20, 20, 20, 20, 20.byte 0, 65, 34, 20, 8.byte 2, 1, 81, 9, 6.byte 50, 73, 121, 65, 62.byte 124, 18, 17, 18, 124.byte 127, 73, 73, 73, 62.byte 62, 65, 65, 65, 34.byte 127, 65, 65, 34, 28.byte 127, 73, 73, 73, 65.byte 127, 9, 9, 9, 1.byte 62, 65, 73, 73, 58.byte 127, 8, 8, 8, 127.byte 0, 65, 127, 65, 0.byte 32, 64, 65, 63, 1.byte 127, 8, 20, 34, 65.byte 127, 64, 64, 64, 64.byte 127, 2, 12, 2, 127.byte 127, 4, 8, 16, 127.byte 62, 65, 65, 65, 62.byte 127, 9, 9, 9, 6.byte 62, 65, 81, 33, 94.byte 127, 9, 25, 41, 70.byte 38, 73, 73, 73, 50.byte 1, 1, 127, 1, 1.byte 63, 64, 64, 64, 63.byte 31, 32, 64, 32, 31.byte 127, 32, 24, 32, 127.byte 99, 20, 8, 20, 99.byte 3, 4, 120, 4, 3.byte 97, 81, 73, 69, 67.byte 0, 127, 65, 65, 0.byte 2, 4, 8, 16, 32.byte 0, 65, 65, 127, 0.byte 4, 2, 1, 2, 4.byte 64, 64, 64, 64, 64.byte 1, 2, 4, 0, 0.byte 32, 84, 84, 84, 120.byte 127, 68, 68, 68, 56.byte 56, 68, 68, 68, 40.byte 56, 68, 68, 68, 127.byte 56, 84, 84, 84, 24.byte 8, 126, 9, 1, 2.byte 8, 84, 84, 84, 60.byte 127, 4, 4, 4, 120.byte 0, 68, 125, 64, 0.byte 32, 64, 64, 61, 0.byte 127, 16, 40, 68, 0.byte 0, 65, 127, 64, 0.byte 124, 4, 24, 4, 120.byte 124, 8, 4, 4, 120.byte 56, 68, 68, 68, 56.byte 124, 20, 20, 20, 24.byte 8, 20, 20, 20, 124.byte 124, 8, 4, 4, 8.byte 72, 84, 84, 84, 32.byte 4, 63, 68, 64, 32.byte 60, 64, 64, 32, 124.byte 28, 32, 64, 32, 28.byte 60, 64, 56, 64, 60.byte 68, 40, 16, 40, 68.byte 12, 80, 80, 80, 60.byte 68, 100, 84, 76, 68.byte 0, 8, 54, 65, 0.byte 0, 0, 119, 0, 0.byte 0, 65, 54, 8, 0.byte 2, 1, 2, 4, 2lcd_inittab_type2:.byte 5, 10.byte 3, 0xa4.byte 4, 0x01.byte 5, 150.byte 3, 0x01.byte 2, 0x01.byte 2, 0x00.byte 3, 0x02.byte 2, 0x03.byte 2, 0x00.byte 3, 0x03.byte 2, 0x12.byte 2, 0x30.byte 3, 0x08.byte 2, 0x04.byte 2, 0x04.byte 3, 0x0e.byte 4, 0x10.byte 3, 0x70.byte 2, 0x10.byte 2, 0x00.byte 3, 0x71.byte 4, 0x01.byte 3, 0x30.byte 4, 0x02.byte 3, 0x31.byte 2, 0x04.byte 2, 0x00.byte 3, 0x32.byte 4, 0x07.byte 3, 0x33.byte 2, 0x05.byte 2, 0x00.byte 3, 0x34.byte 4, 0x07.byte 3, 0x35.byte 2, 0x07.byte 2, 0x03.byte 3, 0x36.byte 2, 0x05.byte 2, 0x07.byte 3, 0x37.byte 4, 0x05.byte 3, 0x38.byte 2, 0x14.byte 2, 0x04.byte 3, 0x39.byte 4, 0x0e.byte 3, 0x40.byte 2, 0x02.byte 2, 0x02.byte 3, 0x41.byte 4, 0x03.byte 3, 0x42.byte 4, 0x00.byte 3, 0x43.byte 2, 0x02.byte 2, 0x00.byte 3, 0x44.byte 2, 0x07.byte 2, 0x07.byte 3, 0x45.byte 2, 0x04.byte 2, 0x07.byte 3, 0x46.byte 2, 0x05.byte 2, 0x05.byte 3, 0x47.byte 4, 0x02.byte 3, 0x48.byte 4, 0x04.byte 3, 0x49.byte 4, 0x04.byte 3, 0x60.byte 2, 0x02.byte 2, 0x02.byte 3, 0x61.byte 4, 0x03.byte 3, 0x62.byte 4, 0x00.byte 3, 0x63.byte 2, 0x02.byte 2, 0x00.byte 3, 0x64.byte 2, 0x07.byte 2, 0x07.byte 3, 0x65.byte 2, 0x04.byte 2, 0x07.byte 3, 0x66.byte 2, 0x05.byte 2, 0x05.byte 3, 0x68.byte 4, 0x04.byte 3, 0x69.byte 4, 0x04.byte 3, 0x07.byte 4, 0x01.byte 3, 0x18.byte 4, 0x01.byte 3, 0x10.byte 2, 0x16.byte 2, 0x90.byte 3, 0x11.byte 2, 0x01.byte 2, 0x00.byte 3, 0x12.byte 2, 0x01.byte 2, 0x17.byte 3, 0x13.byte 2, 0x0f.byte 2, 0x80.byte 3, 0x12.byte 2, 0x01.byte 2, 0x37.byte 3, 0x20.byte 4, 0x00.byte 3, 0x21.byte 4, 0x00.byte 3, 0x50.byte 4, 0x00.byte 3, 0x51.byte 4, 0xaf.byte 3, 0x52.byte 4, 0x00.byte 3, 0x53.byte 4, 0x83.byte 3, 0x90.byte 4, 0x03.byte 3, 0x91.byte 4, 0x00.byte 3, 0x92.byte 2, 0x01.byte 2, 0x01.byte 3, 0x98.byte 2, 0x04.byte 2, 0x00.byte 3, 0x99.byte 2, 0x13.byte 2, 0x02.byte 3, 0x9a.byte 2, 0x02.byte 2, 0x02.byte 3, 0x9b.byte 2, 0x02.byte 2, 0x00.byte 5, 100.byte 3, 0x07.byte 4, 0x21.byte 3, 0x12.byte 2, 0x01.byte 2, 0x37.byte 5, 1.byte 3, 0x07.byte 4, 0x21.byte 3, 0x12.byte 2, 0x11.byte 2, 0x37.byte 5, 100.byte 3, 0x07.byte 2, 0x02.byte 2, 0x33.byte 0lcd_inittab_type3:.byte 1, 0x01.byte 5, 5.byte 1, 0x11.byte 5, 120.byte 1, 0x3a.byte 2, 0x65.byte 1, 0xab.byte 1, 0x35.byte 2, 0x00.byte 1, 0xf2.byte 2, 0x01.byte 1, 0xe0.byte 2, 0x71.byte 2, 0x76.byte 2, 0x25.byte 2, 0x01.byte 2, 0xa5.byte 2, 0x09.byte 2, 0x15.byte 2, 0x11.byte 1, 0xe1.byte 2, 0x40.byte 2, 0x21.byte 2, 0x64.byte 2, 0x13.byte 2, 0xf3.byte 2, 0x0b.byte 2, 0x00.byte 2, 0x00.byte 1, 0xe2.byte 2, 0x71.byte 2, 0x65.byte 2, 0x24.byte 2, 0x08.byte 2, 0x97.byte 2, 0x01.byte 2, 0x15.byte 2, 0x11.byte 1, 0xe3.byte 2, 0x51.byte 2, 0x01.byte 2, 0x62.byte 2, 0x13.byte 2, 0xf3.byte 2, 0x0b.byte 2, 0x00.byte 2, 0x00.byte 1, 0xe4.byte 2, 0x71.byte 2, 0x57.byte 2, 0x31.byte 2, 0x01.byte 2, 0x82.byte 2, 0x04.byte 2, 0x1f.byte 2, 0x11.byte 1, 0xe5.byte 2, 0x64.byte 2, 0x41.byte 2, 0x64.byte 2, 0x19.byte 2, 0xb3.byte 2, 0x09.byte 2, 0x00.byte 2, 0x00.byte 1, 0x29.byte 0lcd_inittab_type7:.byte 1, 0x01.byte 5, 10.byte 1, 0xb4.byte 2, 0x00.byte 1, 0xb6.byte 2, 0x01.byte 1, 0xb7.byte 2, 0x00.byte 2, 0x00.byte 2, 0x02.byte 2, 0x00.byte 2, 0x06.byte 2, 0x26.byte 2, 0x2d.byte 2, 0x27.byte 2, 0x55.byte 2, 0x27.byte 1, 0xb8.byte 2, 0x10.byte 1, 0xb9.byte 2, 0x52.byte 2, 0x12.byte 2, 0x03.byte 1, 0xc0.byte 2, 0x0a.byte 2, 0x10.byte 2, 0x10.byte 1, 0xc2.byte 2, 0x14.byte 2, 0x23.byte 1, 0xc3.byte 2, 0x12.byte 2, 0x23.byte 1, 0xc6.byte 2, 0x48.byte 1, 0xe0.byte 2, 0x20.byte 2, 0x71.byte 2, 0x17.byte 2, 0x09.byte 2, 0x70.byte 2, 0x0c.byte 2, 0x13.byte 2, 0x25.byte 1, 0xe1.byte 2, 0x37.byte 2, 0x00.byte 2, 0x63.byte 2, 0x11.byte 2, 0xd9.byte 2, 0x00.byte 2, 0x12.byte 2, 0x01.byte 1, 0xe2.byte 2, 0x42.byte 2, 0x42.byte 2, 0x60.byte 2, 0x08.byte 2, 0xb4.byte 2, 0x07.byte 2, 0x0e.byte 2, 0x90.byte 1, 0xe3.byte 2, 0x47.byte 2, 0x60.byte 2, 0x66.byte 2, 0x09.byte 2, 0x6a.byte 2, 0x02.byte 2, 0x0e.byte 2, 0x09.byte 1, 0xe4.byte 2, 0x11.byte 2, 0x40.byte 2, 0x03.byte 2, 0x0a.byte 2, 0xc1.byte 2, 0x0d.byte 2, 0x17.byte 2, 0x30.byte 1, 0xe5.byte 2, 0x00.byte 2, 0x30.byte 2, 0x77.byte 2, 0x1c.byte 2, 0xfb.byte 2, 0x00.byte 2, 0x13.byte 2, 0x07.byte 1, 0xe6.byte 2, 0x01.byte 1, 0x35.byte 2, 0x00.byte 1, 0x36.byte 2, 0x00.byte 1, 0xf2.byte 2, 0x40.byte 1, 0xf3.byte 2, 0x50.byte 1, 0xfb.byte 2, 0x01.byte 1, 0x11.byte 5, 200.byte 1, 0xb1.byte 2, 0x16.byte 2, 0x03.byte 1, 0xb2.byte 2, 0x17.byte 2, 0x03.byte 1, 0x3a.byte 2, 0x65.byte 1, 0x29.byte 0recoverytext:.ascii "Entered recovery mode\0".ascii "Connect via USB\0".align 1.code 16thumb_nrv2e_d8:mov r7,r2mov r4,#1; neg r5,r4 @ r5= -1 initial conditionlsl r4,#31 @ 1<<31: refill next timemov r6,#5lsl r6,#8 @ 0x500 @ nrv2e M2_MAX_OFFSETb top_n2enrv2e_done:bx r7get1_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself]ldrb r4,[r0] @ zero-extend next byteadc r4,r4 @ double and insert CarryIn as low bitadd r0,#1lsl r4,#24 @ move to top byte, and set CarryOut from old bit 8mov pc,lr @ return, stay in current (THUMB) modelit_n2e:ldrb r3,[r0]; add r0,#1strb r3,[r2]; add r2,#1top_n2e:add r4,r4; mov lr,pc; beq get1_n2e; bcs lit_n2emov r1,#1; b getoff_n2eoff_n2e:sub r1,#1add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1getoff_n2e:add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1add r4,r4; mov lr,pc; beq get1_n2e; bcc off_n2esub r3,r1,#3 @ set Carrymov r1,#0 @ Carry unaffectedblo offprev_n2e @ r1 was 2; tests Carry onlylsl r3,#8ldrb r5,[r0]; add r0,#1 @ low 7+1 r4orr r5,r3mvn r5,r5; beq nrv2e_done @ r5= ~r5asr r5,#1; bcs lenlast_n2eb lenmore_n2eoffprev_n2e:add r4,r4; mov lr,pc; beq get1_n2e; bcs lenlast_n2elenmore_n2e:mov r1,#1add r4,r4; mov lr,pc; beq get1_n2e; bcs lenlast_n2elen_n2e:add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1add r4,r4; mov lr,pc; beq get1_n2e; bcc len_n2eadd r1,#6-2b gotlen_n2elenlast_n2e:add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1 @ 0,1,2,3add r1,#2gotlen_n2e: @ 'cmn': add the inputs, set condition codes, discard the sumcmn r6,r5; bcs near_n2e @ within M2_MAX_OFFSETadd r1,#1 @ too far away, so minimum match length is 3near_n2e:ldrb r3,[r2] @ force cacheline allocatecopy_n2e:ldrb r3,[r2,r5]strb r3,[r2]; add r2,#1sub r1,#1; bne copy_n2eb top_n2e.code 32.align 2decompress:mov r0, #0x24000000add r0, r0, #0xa000mov r2, #0x08000000adr r12, thumb_nrv2e_d8 + 1bx r12recoverymode:add r0, r11, #0x2100mov r1, #0mov r2, #0xff00orr r2, r2, #0xffadr r3, recoverytextbl rendertextadd r0, r11, #0x2c00bl rendertextmov r0, #0mov r1, #175mov r2, #0mov r3, #131str r11, [sp]bl displaylcdmov r12, #0mov r11, #1MOV R8, #0x38800000MOV R9, #0x3C400000ADD R1, R9, #0x00100000 @ Enable USB clocksLDR R0, [R1,#0x28]BIC R0, R0, #0x4000STR R0, [R1,#0x28]LDR R0, [R1,#0x40]BIC R0, R0, #0x800STR R0, [R1,#0x40]LDR R0, [R8,#0xE00] @ PHY clock enableBIC R0, R0, #3STR R0, [R8,#0xE00]LDR SP, [R8,#0x804]ORR R0, SP, #2STR R0, [R8,#0x804] @ USB2 Gadget: Soft disconnectBL sleep10msMOV R9, #0x3C400000STR R12, [R9] @ USB2 PHY: Power onSTR R11, [R9,#0x1C] @ USB2 PHY: UndocumentedMOV R0, #0xE00ORR R0, R0, #0x3FSTR R0, [R9,#0x44] @ USB2 PHY: UndocumentedLDR R0, [R9,#0x04]BIC R0, R0, #3STR R0, [R9,#0x04] @ USB2 PHY: Clock is 48MHzLDR R4, [R9,#0x08]ORR R1, R4, #1STR R1, [R9,#0x08] @ USB2 PHY: Assert Software ResetBL sleep10msSTR R12, [R9,#0x08] @ USB2 PHY: Deassert Software ResetBL sleep10msSTR R11, [R8,#0x10] @ USB2 Gadget: Assert Core Software Resetwaitcorereset:LDR R0, [R8,#0x10] @ USB2 Gadget: Wait for Core to resetTST R0, #1BNE waitcoreresetTST R0, #0x80000000 @ USB2 Gadget: Wait for AHB IDLEBEQ waitcoreresetMOV R0, #0xB6STR R0, [R8,#0x24] @ USB2 Gadget: RX FIFO size: 728 bytesORR R0, R0, #0x840000STR R0, [R8,#0x28] @ USB2 Gadget: Non-periodic TX FIFO size: 528 bytesMOV R0, #0x26STR R0, [R8,#0x08] @ USB2 Gadget: DMA Enable, Burst Length: 4, Mask InterruptsMOV R0, #0x1400ADD R0, R0, #8STR R0, [R8,#0x0C] @ USB2 Gadget: PHY IF is 16bit, Turnaround 5STR SP, [R8,#0x804] @ USB2 Gadget: Soft reconnect@ fallthroughmainloop:LDR R3, [R8,#0x14] @ Global USB interruptsTST R3, #0x00001000 @ BUS resetBEQ noresetMOV R2, #0x500STR R2, [R8,#0x804]MOV R2, #4STR R2, [R8,#0x800] @ USB2 Gadget: Device Address 0, STALL on non-zero length status stageMOV R2, #0x8000STR R2, [R8,#0x900] @ USB2 Gadget: Endpoint 0 IN Control: ACTIVESTR R2, [R8,#0xB00] @ USB2 Gadget: Endpoint 0 OUT Control: ACTIVESUB R5, R12, #1STR R5, [R8,#0x908] @ USB2 Gadget: Endpoint 0 IN Interrupt: ALLSTR R5, [R8,#0xB08] @ USB2 Gadget: Endpoint 0 OUT Interrupt: ALLLDR R2, val_20080040STR R2, [R8,#0xB10] @ USB2 Gadget: Endpoint 0 OUT Transfer Size: 64 Bytes, 1 Packet, 1 Setup PacketMOV R2, #0x22000000ORR R2, R2, #0x10000STR R2, [R8,#0xB14] @ USB2 Gadget: Endpoint 0 OUT DMA Address: 0x22010000LDR R2, [R8,#0xB00]ORR R2, R2, #0x84000000STR R2, [R8,#0xB00] @ USB2 Gadget: Endpoint 0 OUT Control: ENABLE CLEARNAKLDR R2, val_00088210STR R2, [R8,#0x960] @ USB2 Gadget: Endpoint 3 IN Control: ACTIVE BULK, 528 byte packetsSTR R2, [R8,#0xB80] @ USB2 Gadget: Endpoint 4 OUT Control: ACTIVE BULK, 528 byte packetsSTR R5, [R8,#0x968] @ USB2 Gadget: Endpoint 3 IN Interrupt: ALLSTR R5, [R8,#0xB88] @ USB2 Gadget: Endpoint 4 OUT Interrupt: ALLLDR R2, val_00080210STR R2, [R8,#0xB90] @ USB2 Gadget: Endpoint 4 OUT Transfer Size: 528 Bytes, 1 PacketMOV R2, #0x22000000ORR R2, R2, #0x12000STR R2, [R8,#0xB94] @ USB2 Gadget: Endpoint 4 OUT DMA Address: 0x22012000LDR R2, [R8,#0xB80]ORR R2, R2, #0x94000000STR R2, [R8,#0xB80] @ USB2 Gadget: Endpoint 4 OUT Control: ENABLE CLEARNAK DATA0STR R5, [R8,#0x810] @ USB2 Gadget: IN Endpoint Interrupt Mask: ALLSTR R5, [R8,#0x814] @ USB2 Gadget: OUT Endpoint Interrupt Mask: ALLSTR R5, [R8,#0x81C] @ USB2 Gadget: Enable interrupts on all endpointsnoreset:TST R3, #0x00040000 @ IN endpoint eventBEQ noineventLDR R4, [R8,#0x908] @ Just ACK them all...STR R4, [R8,#0x908]LDR R4, [R8,#0x968]STR R4, [R8,#0x968]noinevent:TST R3, #0x00080000 @ OUT endpoint eventBEQ noouteventLDR R4, [R8,#0xB08]MOVS R4, R4 @ Event on OUT EP0BEQ noep0outTST R4, #8 @ SETUP phase doneBEQ controldoneBL flushcacheMOV R5, #0x22000000ORR R5, R5, #0x10000LDRB R6, [R5,#0x01] @ Get request typeCMP R6, #0BEQ GET_STATUSCMP R6, #1BEQ CLEAR_FEATURECMP R6, #3BEQ SET_FEATURECMP R6, #5BEQ SET_ADDRESSCMP R6, #6BEQ GET_DESCRIPTORCMP R6, #8BEQ GET_CONFIGURATIONCMP R6, #9BEQ SET_CONFIGURATIONctrlstall:LDR R1, [R8,#0x900]ORR R1, R1, #0x00200000STR R1, [R8,#0x900] @ Stall IN EP0LDR R1, [R8,#0xB00]ORR R1, R1, #0x00200000STR R1, [R8,#0xB00] @ Stall OUT EP0controldone:LDR R1, val_20080040STR R1, [R8,#0xB10] @ OUT EP0: 64 Bytes, 1 Packet, 1 Setup PacketMOV R1, #0x22000000ORR R1, R1, #0x10000STR R1, [R8,#0xB14] @ OUT EP0: DMA addressLDR R1, [R8,#0xB00]ORR R1, R1, #0x84000000STR R1, [R8,#0xB00] @ OUT EP0: Enable ClearNAKnoep0out:STR R4, [R8,#0xB08] @ ACK it, whatever it was...LDR R4, [R8,#0xB88]MOVS R4, R4 @ Event on OUT EP4BEQ noep1outTST R4, #1 @ XFER completeBEQ datadoneBL flushcacheMOV R0, #0x22000000ORR LR, R0, #0x800ORR R0, R0, #0x12000LDR R1, [R0]LDR R2, [R0,#0x04]CMP R1, #0 @ EXECUTE, no feedbackMCREQ p15, 0, R12,c7,c5 @ Flush ICacheLDREQ SP, [R0,#0x08]MOVEQ PC, R2CMP R1, #1 @ READBNE noreadLDR R1, [R0,#0x08]MOV R6, R1,LSL#2MOV R0, #0x22000000ORR R0, R0, #0x13000ORR R0, R0, #0x10copydata:LDR R5, [R2], #4STR R5, [R0], #4SUBS R1, R1, #1BNE copydataADD R1, R6, #0x10B sendsuccesscustomsizenoread:CMP R1, #2 @ WRITEBNE sendunknownfuncLDR R1, [R0,#0x08]ADD R0, R0, #0x10copydata2:LDR R5, [R0], #4STR R5, [R2], #4SUBS R1, R1, #1BNE copydata2BL flushcacheMOV R1, #0x10@ fallthroughsendsuccesscustomsize:MOV R2, #0x22000000ORR R2, R2, #0x13000STMIA R2, {R11, R12}@ fallthroughsendlast2zero:STR R12, [R2,#0x08]STR R12, [R2,#0x0C]@ fallthroughdatasend:BL flushcacheLDR R0, val_00088210STR R0, [R8,#0x960] @ EP3 IN: ACTIVE BULK, 528 byte packetsORR R1, R1, #0x20000000 @ 1 Packet at a timeORR R1, R1, #0x00080000 @ 1 PacketSTR R1, [R8,#0x970] @ EP3 IN: 1 Packet, 1 Packet at a time, Size as in R1STR R2, [R8,#0x974] @ EP3 IN: DMA addressLDR R1, [R8,#0x960]ORR R1, R1, #0x84000000STR R1, [R8,#0x960] @ EP3 IN: Enable ClearNAKdatadone:LDR R1, val_00080210STR R1, [R8,#0xB90] @ OUT EP4: 528 Bytes, 1 PacketMOV R1, #0x22000000ORR R1, R1, #0x12000STR R1, [R8,#0xB94] @ Out EP4: DMA addressLDR R1, [R8,#0xB80]ORR R1, R1, #0x84000000STR R1, [R8,#0xB80] @ Out EP4: Enable ClearNAKnoep1out:STR R4, [R8,#0xB88] @ ACK it, whatever it was...nooutevent:STR R3, [R8,#0x14] @ ACK it, whatever it was...B mainloopsendunknownfunc:MOV R0, #2MOV R1, #0x10MOV R2, #0x08400000STMIA R2, {R0, R12}B sendlast2zeroGET_DESCRIPTOR:LDRB R7, [R5,#3] @ Descriptor typeCMP R7, #1ADREQ R0, devicedescriptorBEQ senddescriptorCMP R7, #2ADREQ R0, configurationdescriptorMOVEQ R1, #0x20BEQ senddescriptorcustomsizeCMP R7, #3BNE ctrlstallLDRB R7, [R5,#2] @ String descriptor indexCMP R7, #0ADREQ R0, langstringdescriptorBEQ senddescriptorCMP R7, #1CMPNE R7, #2ADREQ R0, devnamestringdescriptorBNE ctrlstall@ fallthroughsenddescriptor:LDRB R1, [R0] @ Descriptor length@ fallthroughsenddescriptorcustomsize:LDRH R5, [R5,#0x06] @ Requested lengthCMP R5, R1MOVLO R1, R5MOV R2, #0x22000000ORR R2, R2, #0x11000ADD R6, R1, R2copydescriptor:LDR R5, [R0], #4STR R5, [R2], #4CMP R2, R6BCC copydescriptorB ctrlsendGET_STATUS:LDRB R1, [R5]CMP R1, #0x80MOV R0, #0x22000000ORR R0, R0, #0x11000STREQ R11, [R0]STRNE R12, [R0]MOV R1, #0x00000002B ctrlsendCLEAR_FEATURE:LDRB R2, [R5]CMP R2, #2LDREQ R2, [R5,#2]BICEQ R2, R2, #0x00800000CMPEQ R2, #0x00010000@ fallthroughSET_CONFIGURATION:LDREQ R2, [R8,#0x960]ORREQ R2, R2, #0x10000000STREQ R2, [R8,#0x960] @ EP3 IN: Set DATA0 PIDLDREQ R2, [R8,#0xB80]ORREQ R2, R2, #0x10000000STREQ R2, [R8,#0xB80] @ EP4 OUT: Set DATA0 PIDB SET_FEATURE @ zero-length ACKSET_ADDRESS:LDRH R2, [R5,#0x02] @ new addressLDR R1, [R8,#0x800]BIC R1, R1, #0x000007F0ORR R1, R1, R2,LSL#4STR R1, [R8,#0x800] @ set new address@ fallthroughSET_FEATURE:MOV R1, #0 @ zero-length ACKB ctrlsendGET_CONFIGURATION:MOV R1, #0x00000001STR R1, [R0]@ fallthroughctrlsend:BL flushcacheMOV R0, #0x22000000 @ Buffer to be sentORR R0, R0, #0x11000MOV R2, #0x00009800STR R2, [R8,#0x900] @ EP0 IN: ACTIVEORR R1, R1, #0x00080000 @ 1 PacketSTR R1, [R8,#0x910] @ EP0 IN: 1 Packet, Size as in R1STR R0, [R8,#0x914] @ EP0 IN: DMA addressLDR R1, [R8,#0x900]ORR R1, R1, #0x84000000STR R1, [R8,#0x900] @ EP0 IN: Enable ClearNAKB controldoneval_00080210:.word 0x00080210val_00088210:.word 0x00088210val_20080040:.word 0x20080040devicedescriptor:.word 0x02000112.word 0x40FFFFFF.word 0xE112FFFF.word 0x02010001.word 0x00010100configurationdescriptor:.word 0x00200209.word 0xC0000101.word 0x00040932.word 0xFFFF0200.word 0x050700FF.word 0x02100204.word 0x83050701.word 0x01021002langstringdescriptor:.word 0x04090304devnamestringdescriptor:.byte 0x38.byte 3.ascii "e\0m\0B\0I\0O\0S\0 \0L\0o\0a\0d\0e\0r\0 \0R\0e\0c\0o\0v\0e\0r\0y\0 \0I\0N\0\062\0G\0"lcd_initmapping:.word lcd_inittab_type3 - lcd_initmapping_ref.word lcd_inittab_type7 - lcd_initmapping_ref.word lcd_inittab_type2 - lcd_initmapping_ref.word lcd_inittab_type3 - lcd_initmapping_refinitlcd:stmfd sp!, {r4,r5,lr}bl detectlcdsub r12, r12, #0x04900000adr r5, lcd_initmappingadd r5, r5, r0,lsl#2ldr r5, [r5]add r5, r5, pcmov r0, #0xc00lcd_initmapping_ref:orr r0, r0, #1str r0, [r12]mov r0, #0x7f00orr r0, r0, #0xffstr r0, [r12,#0x24]mov r0, #0str r0, [r12,#0x28]mov r0, #1bl sleepmsmov r0, #1str r0, [r12,#0x28]mov r0, #5bl sleepmsinitlcd_loop:adr lr, initlcd_loopldrb r1, [r5], #1ldrb r0, [r5], #1add pc, pc, r1,lsl#2nopldmfd sp!, {r4,r5,pc}b sendlcdcb sendlcddb sendlcd2cb sendlcd2db sleepmssendlcd2c:ldr r4, [r12,#0x1c]ands r4, r4, #0x10bne sendlcd2cmov r4, r0,lsr#8str r4, [r12,#0x04]and r0, r0, #0xffsendlcdc:ldr r4, [r12,#0x1c]ands r4, r4, #0x10bne sendlcdcstr r0, [r12,#0x04]mov pc, lrsendlcd2d:ldr r4, [r12,#0x1c]ands r4, r4, #0x10bne sendlcd2dmov r4, r0,lsr#8str r4, [r12,#0x40]and r0, r0, #0xffsendlcdd:ldr r4, [r12,#0x1c]ands r4, r4, #0x10bne sendlcddstr r0, [r12,#0x40]mov pc, lrdetectlcd:mov r12, #0x3c000000orr r12, r12, #0xf00000ldr r0, [r12,#0xd0]bic r0, r0, #0x0fstr r0, [r12,#0xd0]ldr r0, [r12,#0xe0]bic r0, r0, #0xf0str r0, [r12,#0xe0]ldr r0, [r12,#0xd4]and r0, r0, #1ldr r1, [r12,#0xe4]and r1, r1, #2orr r0, r0, r1mov pc, lrdisplaylcd:stmfd sp!, {r0,r1,r4,lr}bl displaylcd_syncbl detectlcdsub r12, r12, #0x04900000cmp r0, #2bne displaylcd_othertypesmov r0, #0x50bl sendlcd2cldr r0, [sp]bl sendlcd2dmov r0, #0x51bl sendlcd2cldr r0, [sp,#0x04]bl sendlcd2dmov r0, #0x52bl sendlcd2cmov r0, r2bl sendlcd2dmov r0, #0x53bl sendlcd2cmov r0, r3bl sendlcd2dmov r0, #0x20bl sendlcd2cldr r0, [sp]bl sendlcd2dmov r0, #0x21bl sendlcd2cmov r0, r2bl sendlcd2dmov r0, #0x22bl sendlcd2cb displaylcd_blitdisplaylcd_othertypes:mov r0, #0x2abl sendlcdcldr r0, [sp]bl sendlcd2dldr r0, [sp,#0x04]bl sendlcd2dmov r0, #0x2bbl sendlcdcmov r0, r2bl sendlcd2dmov r0, r3bl sendlcd2dmov r0, #0x2cbl sendlcdcdisplaylcd_blit:ldmia sp, {r0,r1}sub r1, r0add r1, r1, #1sub r3, r2add r3, r3, #1mul r2, r1, r3ldr r1, [sp,#0x10]cmp r1, #0x40000000bne displaylcd_dmadisplaylcd_pixel:ldr r0, [sp,#0x14]bl sendlcd2dsubs r2, r2, #1bne displaylcd_pixelldmfd sp!, {r0,r1,r4,pc}displaylcd_dma:mov r3, #0x38000000add r3, r3, #0x400000mov r0, #0x20000000orr r0, r0, #0x180000str r0, [r3,#0x104]str r1, [r3,#0x100]mov r0, r2,lsr#1sub r0, r0, #1str r0, [r3,#0x108]bl flushcachemov r0, #4str r0, [r3,#0x114]ldmfd sp!, {r0,r1,r4,pc}displaylcd_sync:mov r1, #0x38000000add r1, r1, #0x400000displaylcd_sync_wait:ldr r0, [r1,#0x184]tst r0, #0x40000bne displaylcd_sync_waitmov pc, lrgetpowerok:stmfd sp!, {lr}mov r0, #0xe6mov r1, #0x19bl i2crecvbyteeor r0, r0, #1ands r0, r0, #1ldmnefd sp!, {pc}mov r0, #0xe6mov r1, #0x4bbl i2crecvbyteands r0, r0, #4movne r0, #1ldmnefd sp!, {pc}mov r0, #0xe6mov r1, #0x12bl i2crecvbyteands r0, r0, #4movne r0, #1ldmfd sp!, {pc}poweroff:mov r0, #0xe6mov r1, #0x0cmov r2, #0x01bl i2csendbyteb poweroffi2csendbyte:mov r3, #0@fallthroughi2csend:stmfd sp!, {r4,lr}mov r12, #0x3C000000add r12, r12, #0x00900000mov r4, #0str r4, [r12,#0x08]str r0, [r12,#0x0c]mov r4, #0xf0str r4, [r12,#0x04]mov r4, #0xf3str r4, [r12]bl i2cwaitstr r1, [r12,#0x0c]str r4, [r12]bl i2cwaitmovs r3, r3moveq r0, r2i2csend_write:ldrne r0, [r2], #1str r0, [r12,#0x0c]str r4, [r12]bl i2cwaitsubs r3, r3, #1bhi i2csend_writemov r0, #0xd0str r0, [r12,#0x04]str r4, [r12]i2csend_wait:ldr r0, [r12,#0x04]tst r0, #0x20bne i2csend_waitldmfd sp!, {r4,pc}i2crecvbyte:mov r2, #0mov r3, #1@fallthroughi2crecv:stmfd sp!, {r0,r4,lr}mov r12, #0x3C000000add r12, r12, #0x00900000mov r4, #0str r4, [r12,#0x08]str r0, [r12,#0x0c]mov r4, #0xf0str r4, [r12,#0x04]mov r4, #0xf3str r4, [r12]bl i2cwaitstr r1, [r12,#0x0c]str r4, [r12]bl i2cwaitldr r0, [sp]orr r0, r0, #1str r1, [r12,#0x0c]mov r0, #0xb0str r0, [r12,#0x04]str r4, [r12]bl i2cwaiti2crecv_read:subs r3, r3, #1moveq r4, #0x73str r4, [r12]bl i2cwaitldr r0, [r12,#0x0c]movs r2, r2strne r0, [r2], #1movs r3, r3bne i2crecv_readmov r1, #0x90str r1, [r12,#0x04]mov r1, #0xf3str r1, [r12]i2crecv_wait:ldr r1, [r12,#0x04]tst r1, #0x20bne i2crecv_waitldmfd sp!, {r0,r4,pc}i2cwait:ldr r0, [r12]tst r0, #0x10beq i2cwaitmov pc, lrsleep10ms:mov r0, #10@ fallthroughsleepms:mov r2, #0xc8mul r1, r0, r2mov r2, #0x3c000000orr r2, r2, #0x700000ldr r0, [r2,#0x80]ldr r0, [r2,#0x84]add r1, r1, r0sleepmsloop:ldr r0, [r2,#0x80]ldr r0, [r2,#0x84]cmp r0, r1bmi sleepmsloopmov pc, lr