freemyipod r973 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r972‎ | r973 | r974 >
Date:21:07, 8 March 2017
Author:user890104
Status:new
Tags:
Comment:
Add incomplete emCORE loader for Nano 4G
Modified paths:
  • /emcore/trunk/loader/ipodnano4g (added) (history)
  • /emcore/trunk/loader/ipodnano4g/Makefile (added) (history)
  • /emcore/trunk/loader/ipodnano4g/SOURCES (added) (history)
  • /emcore/trunk/loader/ipodnano4g/ls.x (added) (history)
  • /emcore/trunk/loader/ipodnano4g/main.S (added) (history)
  • /emcore/trunk/loader/ipodnano4g/version.h (added) (history)

Diff [purge]

Index: emcore/trunk/loader/ipodnano4g/SOURCES
@@ -0,0 +1 @@
 2+main.c
Index: emcore/trunk/loader/ipodnano4g/ls.x
@@ -0,0 +1,21 @@
 2+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
 3+ "elf32-littlearm")
 4+OUTPUT_ARCH(arm)
 5+ENTRY(_start)
 6+
 7+SECTIONS
 8+{
 9+ . = 0x22000050;
 10+
 11+ .text : { *(.text) }
 12+
 13+ __data_start__ = . ;
 14+ .data : { *(.data) *(.rodata) }
 15+
 16+ __bss_start__ = .;
 17+ .bss : {
 18+ *(.bss) *(COMMON);
 19+ __bss_end__ = . ;
 20+ }
 21+
 22+}
\ No newline at end of file
Index: emcore/trunk/loader/ipodnano4g/main.S
@@ -0,0 +1,1228 @@
 2+@
 3+@
 4+@ emCORE Loader for iPod Nano 4G
 5+@
 6+@ Copyright 2011 TheSeven, Farthen
 7+@
 8+@
 9+@ This file is part of emCORE.
 10+@
 11+@ emCORE is free software: you can redistribute it and/or
 12+@ modify it under the terms of the GNU General Public License as
 13+@ published by the Free Software Foundation, either version 2 of the
 14+@ License, or (at your option) any later version.
 15+@
 16+@ emCORE is distributed in the hope that it will be useful,
 17+@ but WITHOUT ANY WARRANTY; without even the implied warranty of
 18+@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 19+@ See the GNU General Public License for more details.
 20+@
 21+@ You should have received a copy of the GNU General Public License along
 22+@ with emCORE. If not, see <http://www.gnu.org/licenses/>.
 23+@
 24+@
 25+
 26+
 27+#include "build/version.h"
 28+
 29+
 30+.global _start
 31+_start:
 32+ msr cpsr_c, #0xd3
 33+ mrc p15, 0, r0,c1,c0
 34+ bic r0, r0, #1
 35+ mcr p15, 0, r0,c1,c0 @ disable mmu
 36+
 37+ mov lr, #0
 38+ adr sp, values1
 39+ mcr p15, 0, lr,c7,c14,0 @ clean & invalidate data cache
 40+ mcr p15, 0, lr,c7,c10,4 @ drain write buffer
 41+ mcr p15, 0, lr,c7,c5 @ invalidate instruction cache
 42+ mcr p15, 0, lr,c7,c5,4 @ flush prefetch buffer
 43+ mcr p15, 0, lr,c8,c7 @ invalidate all unlocked entries in the TLB
 44+ mcr p15, 0, lr,c13,c0,0 @ disable context id register
 45+
 46+
 47+.macro block0_constpool @ Block 0 (MMU, DMA) register map:
 48+ @ R0: Unused
 49+ @ R1: Unused
 50+ @ R2: Unused
 51+ @ R3: Scratchpad
 52+ .word 0x00000FFF @ R4: DMA maximum transfer size
 53+ .word 0x00012C00 @ R5: LCD framebuffer pixel count
 54+ .word 0x22006800 @ R6: LCD framebuffer address
 55+ .word 0x38300040 @ R7: LCD data port address
 56+ .word 0x2202D000 @ R8: LCD DMA linked list address
 57+ .word 0x74240000 @ R9: LCD DMA channel settings
 58+ .word 0x0005187D @ R10: CP15r1
 59+ .word 0x2202C000 @ R11: First level page table
 60+ .word 0x00000C1E @ R12: Default segment flags
 61+ @ R13: Constant pool pointer
 62+.endm @ R14: 0
 63+
 64+ ldmia sp!, {r4-r12}
 65+ mcr p15, 0, r11,c2,c0 @ set first level translation table
 66+ mov r3, #-1
 67+ mcr p15, 0, r3,c3,c0 @ disable domain access control @ R3: Unused
 68+ orr r0, r12, #0x22000000
 69+ str r0, [r11], #4
 70+ add r12, r12, #0x00100000
 71+mmuloop:
 72+ str r12, [r11], #4
 73+ add r12, r12, #0x00100000
 74+ cmp r12, #0x38000000
 75+ biccs r12, r12, #0xc
 76+ tst r12, #0x40000000
 77+ beq mmuloop
 78+ @ R11: LCD DMA descriptor head
 79+ @ R12: Unused
 80+ mcr p15, 0, r10,c1,c0 @ R10: Unused
 81+
 82+dmaloop:
 83+ add r8, r8, #0x10
 84+ bic r9, r9, r4
 85+ cmp r4, r5
 86+ movcs r4, r5
 87+ movcs r8, #0
 88+ orr r9, r9, r4
 89+ stmia r11!, {r6-r9}
 90+ add r6, r6, r4,lsl#1
 91+ subs r5, r5, r4
 92+ bne dmaloop
 93+
 94+.macro block1_constpool @ Block 1 (SYSCON) register map:
 95+ .word 0x000327E5 @ R0: PWRCON(0)
 96+ .word 0xFE2BED6D @ R1: PWRCON(1)
 97+ .word 0x00DCF779 @ R2: PWRCON(4)
 98+ .word 0x003E3E00 @ R3
 99+ .word 0x06008501 @ R4
 100+ .word 0x00009DBC @ R5
 101+ .word 0x00404040 @ R6
 102+ .word 0x40001000 @ R7
 103+ .word 0x80008000 @ R8
 104+ .word 0x38501000 @ R9
 105+ .word 0xE02BED4D @ R10: PWRCON(1) during timer setup
 106+ .word 0x001CF700 @ R11: PWRCON(4) during timer setup
 107+ .word 0x3C500000 @ R12: SYSCON base address
 108+ @ R13: Constant pool pointer
 109+.endm @ R14: 0
 110+
 111+ ldmia sp!, {r0-r12}
 112+ str r0, [r12,#0x48] @ PWRCON0 ... @ R0: Scratchpad
 113+ str r1, [r12,#0x4c]
 114+ mov r0, #0x73
 115+ str r0, [r12,#0x58]
 116+ mov r0, #0xff
 117+ str r0, [r12,#0x68]
 118+ str r2, [r12,#0x6c] @ ... PWRCON4
 119+ str lr, [r12]
 120+sysconwait1:
 121+ ldr r0, [r12]
 122+ tst r0, #0xf
 123+ bne sysconwait1 @ while ([SYSCON] & 0xf)
 124+
 125+ str lr, [r12,#0x04]
 126+sysconwait2:
 127+ ldr r0, [r12,#0x04]
 128+ tst r0, r3
 129+ bne sysconwait2 @ while ([SYSCON+4] & 0x003E3E00)
 130+
 131+ mov r0, #0x7
 132+ str r0, [r12,#0x44]
 133+ str lr, [r12,#0x44]
 134+ str lr, [r12,#0x3c]
 135+ str r4, [r12,#0x20] @ R4: Scratchpad
 136+ str r5, [r12,#0x30]
 137+ mov r5, #1 @ R5: 1
 138+ str r5, [r12,#0x44]
 139+ orr r4, r0, #0x10000
 140+ str r4, [r12,#0x44]
 141+sysconwait3:
 142+ ldr r4, [r12,#0x40]
 143+ tst r4, #0x1
 144+ beq sysconwait3 @ while (!([SYSCON+0x40] & 1))
 145+
 146+ str r6, [r12,#0x04] @ R6: Unused
 147+ add r3, r3, #0x3e @ R3: 0x003E3E3E
 148+sysconwait4:
 149+ ldr r4, [r12,#0x04]
 150+ tst r4, r3 @ R3: Unused
 151+ bne sysconwait4
 152+
 153+ str r7, [r12] @ R7: Unused
 154+sysconwait5:
 155+ ldr r2, [r12]
 156+ tst r4, #0xf
 157+ bne sysconwait5
 158+
 159+ str r8, [r12,#0x08]
 160+ orr r4, r8, r8,lsr#1 @ R8: Unused
 161+ str r4, [r12,#0x0c]
 162+ mov r4, #0xc000
 163+ str r4, [r12,#0x10]
 164+ mov r4, #0x8000
 165+ str r4, [r12,#0x14]
 166+ str r4, [r12,#0x70]
 167+ mov r4, #2
 168+ str r4, [r9] @ R9: Unused
 169+ mov r0, #0x10 @ R5: 0x10
 170+
 171+ @ Block 2 (TIMER) register map:
 172+ @ R0: 1
 173+ @ R1: PWRCON(1)
 174+ @ R2: PWRCON(4)
 175+ @ R3: Scratchpad
 176+ @ R4: Scratchpad
 177+ @ R5: 0x10
 178+ @ R6: Unused
 179+ @ R7: Unused
 180+ @ R8: Unused
 181+ @ R9: Unused
 182+ @ R10: PWRCON(1) during timer setup
 183+ @ R11: PWRCON(4) during timer setup
 184+ @ R12: SYSCON base address
 185+ @ R13: Constant pool pointer
 186+ @ R14: 0
 187+
 188+ str r10, [r12,#0x4c] @ PWRCON(1) for timer setup @ R10: Unused
 189+ mov r4, #0x13
 190+ str r4, [r12,#0x58] @ PWRCON(2) for timer setup
 191+ str r11, [r12,#0x6c] @ PWRCON(4) for timer setup @ R11: Unused
 192+ orr r11, r12, #0x00200000 @ R11: TIMER base address
 193+ str r0, [r11,#0x4] @ TACMD = 0x10
 194+ str r0, [r11,#0x24] @ TBCMD = 0x10
 195+ str r0, [r11,#0x44] @ TCCMD = 0x10
 196+ str r0, [r11,#0x64] @ TDCMD = 0x10
 197+ mov r3, #0x40
 198+ str r3, [r11,#0xa0] @ TECON = 0x40
 199+ mov r3, #0xb
 200+ str r3, [r11,#0xb0] @ TEPRE = 0xb
 201+ mov r4, #-1 @ R4: -1
 202+ str r4, [r11,#0xa8] @ TEDATA0 = 0xFFFFFFFF
 203+ mov r3, #0x3
 204+ str r3, [r11,#0xa4] @ TECMD = 0x3
 205+ str r0, [r11,#0xc4] @ TFCMD = 0x10
 206+ str r0, [r11,#0xe4] @ TGCMD = 0x10
 207+ str r0, [r11,#0x104] @ THCMD = 0x10
 208+ str r4, [r11,#0x118] @ THCMD = 0xFFFFFFFF
 209+ str r1, [r12,#0x4c] @ PWRCON(1) @ R1: Unused
 210+ mov r3, #0x73
 211+ str r3, [r12,#0x58] @ PWRCON(2)
 212+ str r2, [r12,#0x6c] @ PWRCON(4) @ R2: Unused
 213+ orr r10, r11, #0x00800000 @ R10: GPIO base address
 214+
 215+ @ Block 3 (GPIO) register map:
 216+ @ R0: Unused
 217+ @ R1: Unused
 218+ @ R2: Unused
 219+ @ R3: Scratchpad
 220+ @ R4: -1
 221+ @ R5: 1
 222+ @ R6: Unused
 223+ @ R7: Unused
 224+ @ R8: Unused
 225+ @ R9: Unused
 226+ @ R10: GPIO base address
 227+ @ R11: TIMER base address
 228+ @ R12: SYSCON base address
 229+ @ R13: Constant pool pointer
 230+ @ R14: 0
 231+
 232+.macro gpio_initdata
 233+ .word 0x3202EEEE @ PCON0
 234+ .word 0xE0EE2253 @ PCON1
 235+ .word 0x2223EEEE @ PCON2
 236+ .word 0x33333332 @ PCON3
 237+ .word 0xFF333E33 @ PCON4
 238+ .word 0xE0FEE200 @ PCON5
 239+ .word 0x2222222E @ PCON6
 240+ .word 0x22222222 @ PCON7
 241+ .word 0xEEEEEEE2 @ PCON8
 242+ .word 0xEEE0EEEE @ PCON9
 243+ .word 0x2EEEEEEE @ PCONA
 244+ .word 0xEEEE0222 @ PCONB
 245+ .word 0xEEEEE00E @ PCONC
 246+ .word 0xEEEEEEEE @ PCOND
 247+ .word 0xEEEEEEEE @ PCONE
 248+.endm
 249+
 250+ ldr r3, [sp], #0x4
 251+ str r3, [r10], #0xc @ R10: PCONx iterator
 252+ mov r3, #0x20
 253+ str r3, [r10], #0x4 @ PCON0 + 0xc = 0x20
 254+ mov r3, #0x40
 255+ str r3, [r10], #0x10 @ PCON0 + 0x10 = 0x40
 256+ add r9, r10, #0x1a0 @ R9: Iterator limit
 257+gpioloop1:
 258+ ldr r3, [sp], #0x4
 259+ str r3, [r10], #0xc
 260+ str lr, [r10], #0x4 @ PCON + 0xc = 0
 261+ str lr, [r10], #0x10 @ PCON + 0x10 = 0
 262+ cmp r10, r9
 263+ bls gpioloop1
 264+ @ R10: 0x3CF001E0
 265+ ldr r3, [r10,#0x1a8]
 266+ bic r3, r3, #2
 267+ orr r3, r3, #1
 268+ str r3, [r10,#0x1a8]
 269+ sub r8, r11, #0x00300000 @ R8: 0x39700000 (iterator)
 270+ mov r9, #6 @ R9: Iterations remaining
 271+gpioloop2:
 272+ str r14, [r8,#0x80]
 273+ str r4, [r8,#0xa0]
 274+ str r14, [r8,#0xc0]
 275+ str r14, [r8,#0xe0]
 276+ add r8, r8, #4
 277+ subs r9, r9, #1
 278+ bne gpioloop2
 279+ @ R9: 0
 280+ ldr r8, [r10,#-0x180] @ R8: PCON3 backup
 281+ and r3, r8, #0xff
 282+ str r3, [r10,#-0x180] @ *PCON3 &= 0xff
 283+ mov r0, #0x3e8 @ R0: Scratchpad
 284+ bl udelay @ R14: Return address
 285+ ldr r3, [r10,#-0x17c]
 286+ and r3, r3, #0xfc
 287+ mov r6, r3, lsr #0x2 @ R6: Data for first PMU access
 288+ str r8, [r10,#-0x180]
 289+ bic r10, r11, #0x00100000 @ R10: I2C base address
 290+
 291+ @ Block 4 (I2C) register map:
 292+ @ R0: Scratchpad
 293+ @ R1: Scratchpad
 294+ @ R2: Unused
 295+ @ R3: Unused
 296+ @ R4: -1
 297+ @ R5: 1
 298+ @ R6: Data for first PMU access
 299+ @ R7: Unused
 300+ @ R8: Unused
 301+ @ R9: 0
 302+ @ R10: I2C base address
 303+ @ R11: TIMER base address
 304+ @ R12: SYSCON base address
 305+ @ R13: Constant pool pointer
 306+ @ R14: Return address / Scratchpad
 307+
 308+ bl i2cwaitrdy
 309+ mov r1, #0x40
 310+ str r1, [r10,#0x08]
 311+ bl i2cwaitrdy
 312+ str r5, [r10,#0x14]
 313+ bl i2cwaitrdy
 314+ str r9, [r10,#0x18]
 315+ bl i2cwaitrdy
 316+ mov r0, #0x80
 317+ str r0, [r10,#0x04]
 318+ bl i2cwaitrdy
 319+ str r9, [r10]
 320+ bl i2cwaitrdy
 321+ str r9, [r10,#0x04]
 322+ bl i2cwaitrdy
 323+ str r1, [r10,#0x0c]
 324+ bl i2cwaitrdy
 325+ orr r0, r5, #0x180
 326+ str r0, [r10]
 327+ bl i2cwaitrdy
 328+ mov r0, #0x10
 329+ str r0, [r10,#0x04]
 330+ bl i2cwaitrdy
 331+
 332+ @ Block 5 (PMU) register map:
 333+ @ R0: Address / Scratchpad (trashed by pmubatch)
 334+ @ R1: Data / Scratchpad (trashed by pmubatch)
 335+ @ R2: Scratchpad (set to 0xb7 by pmu accesses)
 336+ @ R3: Scratchpad (set to 0x10 by pmu accesses)
 337+ @ R4: Scratchpad (trashed by pmu accesses)
 338+ @ R5: 1
 339+ @ R6: Data for first PMU access
 340+ @ R7: Scratchpad (trashed by pmubatch)
 341+ @ R8: Used to store warmboot flag
 342+ @ R9: 0 / pmubatch transfer count (reset to 0 by pmubatch)
 343+ @ R10: I2C base address
 344+ @ R11: TIMER base address
 345+ @ R12: SYSCON base address
 346+ @ R13: Constant pool / pmubatch data pointer
 347+ @ R14: Return address / Scratchpad
 348+
 349+ mov r0, #0x7f
 350+ mov r1, r6
 351+ bl pmuwrite
 352+ mov r0, #0x02
 353+ bl pmuread
 354+ ands r8, r1, #0x80 @ R8: Warmboot flag
 355+ beq pmu_coldboot
 356+ mov r1, #0x80
 357+ bl pmuwrite
 358+pmu_coldboot:
 359+.macro pmu_batch_1
 360+pmu_batch_1_begin:
 361+ .byte 0x14, 0x13
 362+ .byte 0x15, 0x0d
 363+ .byte 0x0b, 0x22
 364+pmu_batch_1_end:
 365+.endm
 366+ mov r9, #(pmu_batch_1_end - pmu_batch_1_begin) / 2
 367+ bl pmubatch
 368+ tst r6, #1 @ R6: Unused
 369+ beq pmu_skip
 370+ mov r0, #0x0d
 371+ bl pmuread
 372+ and r1, r1, #0xdf
 373+ bl pmuwrite
 374+pmu_skip:
 375+.macro pmu_batch_2
 376+pmu_batch_2_begin:
 377+ .byte 0x1f, 0x14
 378+ .byte 0x1a, 0xb2
 379+ .byte 0x1a, 0xb2
 380+ .byte 0x19, 0x14
 381+ .byte 0x21, 0x06
 382+ .byte 0x1d, 0x12
 383+pmu_batch_2_end:
 384+.endm
 385+ mov r9, #(pmu_batch_2_end - pmu_batch_2_begin) / 2
 386+ bl pmubatch
 387+ mov r0, #0x10
 388+ bl pmuread
 389+ bic r1, r1, #0x80
 390+ orr r1, r1, #0x60
 391+ bl pmuwrite
 392+.macro pmu_batch_3
 393+pmu_batch_3_begin:
 394+ .byte 0x44, 0x72
 395+pmu_batch_3_end:
 396+.endm
 397+ mov r9, #(pmu_batch_3_end - pmu_batch_3_begin) / 2
 398+ bl pmubatch
 399+ mov r0, #0x40
 400+ bl pmuread
 401+ orr r1, r1, #0x40
 402+ bl pmuwrite
 403+ mov r0, #0x33
 404+ bl pmuread
 405+ and r1, r1, #0x03
 406+ orr r1, r1, #0x50
 407+ bl pmuwrite
 408+ mov r0, #0x34
 409+ bl pmuread
 410+ and r1, r1, #0x80
 411+ orr r1, r1, #0x54
 412+ bl pmuwrite
 413+.macro pmu_batch_4
 414+pmu_batch_4_begin:
 415+ .byte 0x22, 0x00
 416+ .byte 0x07, 0x50
 417+ .byte 0x08, 0xfe
 418+ .byte 0x09, 0x2b
 419+ .byte 0x01, 0xff
 420+ .byte 0x02, 0xff
 421+ .byte 0x03, 0xff
 422+pmu_batch_4_end:
 423+.endm
 424+ mov r9, #(pmu_batch_4_end - pmu_batch_4_begin) / 2
 425+ bl pmubatch
 426+ cmp r8, #0
 427+ bne pmu_warmboot
 428+ mov r0, #0x30
 429+ mov r1, #0x64
 430+ bl pmuwrite
 431+pmu_warmboot:
 432+ mov r0, #0x31
 433+ bl pmuread
 434+ bic r1, r1, #0x01
 435+ bl pmuwrite
 436+.macro pmu_batch_5
 437+pmu_batch_5_begin:
 438+ .byte 0x0a, 0x70
 439+ .byte 0x13, 0x02
 440+pmu_batch_5_end:
 441+.endm
 442+ mov r9, #(pmu_batch_5_end - pmu_batch_5_begin) / 2
 443+ bl pmubatch
 444+
 445+ orr lr, r11, #0x00800000 @ R14: GPIO base address
 446+ str r9, [lr,#0x384]
 447+ orr lr, r11, #0x01000000 @ R14: MIU base address
 448+ str r5, [lr]
 449+ ldrh r0, [sp], #2
 450+ str r0, [lr,#0x100]
 451+ mov r0, #0xff
 452+ str r0, [lr,#0x11c]
 453+ str r0, [lr,#0x120]
 454+
 455+.macro block6_constpool @ Block 6 (SDRAM) register map:
 456+ .hword 0x1030
 457+ .word 0x008AAC25 @ R0
 458+ .word 0x050D67E5 @ R1
 459+ .word 0x0002000B @ R2
 460+ .word 0x0003B3B2 @ R3
 461+ .word 0xFF53B3B0 @ R4
 462+ .word 0x00008040 @ R5
 463+ .word 0x8000100F @ R6: For LCD init at end of block
 464+ .word 0x41000c20 @ R7: For LCD init at end of block
 465+ @ R8: Warmboot flag
 466+ @ R9: 0
 467+ @ R10: I2C base address
 468+ @ R11: TIMER base address
 469+ @ R12: SYSCON base address
 470+ @ R13: Constant pool pointer
 471+.endm @ R14: MIU base address
 472+
 473+ ldmia sp!, {r0-r7}
 474+ str r0, [lr,#0x114] @ R0: Unused
 475+ str r1, [lr,#0x124] @ R1: Unused
 476+ mov r0, #8 @ R0: Scratchpad
 477+ str r0, [lr,#0x118]
 478+ str r2, [lr,#0x108]
 479+ mov r0, #4
 480+ str r0, [lr,#0x148]
 481+ str r9, [lr,#0x14c]
 482+ str r3, [lr,#0x140]
 483+miu_wait1:
 484+ ldr r0, [lr,#0x140]
 485+ tst r0, #2
 486+ beq miu_wait1
 487+ add r0, r3, #1 @ R3: Unused
 488+ str r0, [lr,#0x140]
 489+miu_wait2:
 490+ ldr r0, [lr,#0x144]
 491+ mvn r0, r0
 492+ tst r0, #3
 493+ bne miu_wait2
 494+ ldr r1, [lr,#0x144] @ R1: Scratchpad
 495+ mov r0, #0x0ff00000
 496+ and r0, r0, r1, lsl#2
 497+ add r0, r0, r4 @ R4: Unused
 498+ str r0, [lr,#0x140]
 499+ mov r0, #0x10
 500+ str r0, [lr,#0x150]
 501+ cmp r8, #0 @ R8: Unused
 502+ sub r8, r10, #0x04300000 @ R8: LCD base address
 503+ str r6, [r12,#0x08] @ R6: Unused
 504+ str r7, [r8] @ R7: Unused
 505+ mov r0, #0x11
 506+ str r0, [r8,#0x20]
 507+ mov r3, #0x33 @ R3: 0x33
 508+ beq miu_coldboot
 509+ str r0, [lr,#0x104]
 510+ b miu_common
 511+miu_coldboot:
 512+ str r3, [lr,#0x104]
 513+ orr r0, r3, #0x200
 514+ str r0, [lr,#0x104]
 515+miu_wait3:
 516+ ldr r0, [lr,#0x104]
 517+ tst r0, #0x110000
 518+ bne miu_wait3
 519+ str r3, [lr,#0x104]
 520+ str r3, [lr,#0x104]
 521+ str r3, [lr,#0x104]
 522+ orr r1, r3, #0x300
 523+ str r1, [lr,#0x104]
 524+miu_wait4:
 525+ ldr r0, [lr,#0x104]
 526+ tst r0, #0x110000
 527+ bne miu_wait4
 528+ str r3, [lr,#0x104]
 529+ str r3, [lr,#0x104]
 530+ str r3, [lr,#0x104]
 531+ str r1, [lr,#0x104]
 532+miu_wait5:
 533+ ldr r0, [lr,#0x104]
 534+ tst r0, #0x110000
 535+ bne miu_wait5
 536+ str r3, [lr,#0x104]
 537+ str r3, [lr,#0x104]
 538+ str r3, [lr,#0x104]
 539+ str r3, [lr,#0x110]
 540+ orr r0, r3, #0x100
 541+ str r0, [lr,#0x104]
 542+miu_wait6:
 543+ ldr r0, [lr,#0x104]
 544+ tst r0, #0x110000
 545+ bne miu_wait6
 546+ str r3, [lr,#0x104]
 547+ str r3, [lr,#0x104]
 548+ str r3, [lr,#0x104]
 549+ str r5, [lr,#0x110] @ R5: Unused
 550+ str r1, [lr,#0x104]
 551+miu_wait7:
 552+ ldr r0, [lr,#0x104]
 553+ tst r0, #0x110000
 554+ bne miu_wait7
 555+ str r3, [lr,#0x104]
 556+ str r3, [lr,#0x104]
 557+miu_common:
 558+ str r3, [lr,#0x104] @ R3: Unused
 559+ mov r0, #0x40
 560+ str r0, [lr,#0x10c]
 561+ ldr r0, [lr,#0x100]
 562+ orr r0, r0, #0x9100000
 563+ str r0, [lr,#0x100]
 564+ mov r0, #0x19
 565+ str r0, [lr,#0x11c]
 566+ mov r0, #1
 567+ str r0, [lr,#0x120]
 568+ orr r1, r2, #0x1000 @ R2: Unused
 569+ str r1, [lr,#0x108]
 570+ str r0, [lr,#0x08]
 571+ mov r1, #0x3e000000
 572+ mov r0, #0x1f
 573+ str r0, [r1,#0x08]
 574+
 575+ @ Block 7 (LCD) register map:
 576+ @ R0: Cmd/Data to be written / Scratchpad
 577+ @ R1: Scratchpad
 578+ @ R2: Scratchpad
 579+ @ R3: Scratchpad
 580+ @ R4: Scratchpad
 581+ @ R5: Scratchpad
 582+ @ R6: Unused
 583+ @ R7: Unused
 584+ @ R8: LCD base address
 585+ @ R9: 0
 586+ @ R10: I2C base address
 587+ @ R11: TIMER base address
 588+ @ R12: SYSCON base address
 589+ @ R13: LCD init script pointer / Scratchpad
 590+ @ R14: Return address / Scratchpad
 591+
 592+.macro lcd_sequences
 593+lcd_sequences_begin:
 594+ .word lcd_sequence_c4 - lcd_sequences_begin
 595+ .word lcd_sequence_d5 - lcd_sequences_begin
 596+ .word lcd_sequence_e6 - lcd_sequences_begin
 597+ .word lcd_sequence_b3 - lcd_sequences_begin
 598+lcd_sequence_b3:
 599+.byte 0x01, 0x11, 0xf8, 0x01, 0x13, 0x01, 0x29, 0x80
 600+ .byte 0x01, 0x11
 601+ .byte 0xf8
 602+ .byte 0x02, 0xfe, 0x00
 603+ .byte 0x02, 0xef, 0x80
 604+ .byte 0x02, 0xc0, 0x0c
 605+ .byte 0x02, 0xc1, 0x03
 606+ .byte 0x03, 0xc2, 0x12, 0x00
 607+ .byte 0x03, 0xc3, 0x12, 0x00
 608+ .byte 0x03, 0xc4, 0x12, 0x00
 609+ .byte 0x03, 0xc5, 0x3a, 0x3e
 610+ .byte 0x03, 0xb1, 0x6a, 0x15
 611+ .byte 0x03, 0xb2, 0x5f, 0x3f
 612+ .byte 0x03, 0xb3, 0x5f, 0x3f
 613+ .byte 0x02, 0xb4, 0x02
 614+ .byte 0x03, 0xb6, 0x12, 0x02
 615+ .byte 0x02, 0x35, 0x00
 616+ .byte 0x02, 0x26, 0x10
 617+ .byte 0x0c, 0xe0, 0x0f, 0x42, 0x24, 0x01, 0x00, 0x02, 0xa6, 0x98, 0x05, 0x04, 0x15
 618+ .byte 0x0c, 0xe1, 0x00, 0x21, 0x44, 0x02, 0x0f, 0x05, 0x89, 0x6a, 0x02, 0x15, 0x04
 619+ .byte 0x0c, 0xe2, 0x7e, 0x04, 0x43, 0x40, 0x00, 0x02, 0x13, 0x00, 0x00, 0x01, 0x0b
 620+ .byte 0x0c, 0xe3, 0x40, 0x40, 0x03, 0x74, 0x0e, 0x00, 0x00, 0x31, 0x02, 0x0b, 0x01
 621+ .byte 0x0c, 0xe4, 0x5a, 0x43, 0x67, 0x56, 0x00, 0x02, 0x67, 0x72, 0x00, 0x05, 0x12
 622+ .byte 0x0c, 0xe5, 0x50, 0x66, 0x47, 0x53, 0x0a, 0x00, 0x27, 0x76, 0x02, 0x12, 0x05
 623+ .byte 0x02, 0x3a, 0x06
 624+ .byte 0x01, 0x13
 625+ .byte 0x01, 0x29
 626+ .byte 0x80
 627+lcd_sequence_c4:
 628+ .byte 0x01, 0x01
 629+ .byte 0x85
 630+ .byte 0x02, 0xc0, 0x00
 631+ .byte 0x02, 0xc1, 0x03
 632+ .byte 0x02, 0xc2, 0x34
 633+ .byte 0x03, 0xc3, 0x72, 0x03
 634+ .byte 0x03, 0xc4, 0x73, 0x03
 635+ .byte 0x03, 0xc5, 0x3c, 0x3c
 636+ .byte 0x02, 0xfe, 0x00
 637+ .byte 0x03, 0xb1, 0x6a, 0x15
 638+ .byte 0x03, 0xb2, 0x6a, 0x15
 639+ .byte 0x03, 0xb3, 0x6a, 0x15
 640+ .byte 0x02, 0xb4, 0x02
 641+ .byte 0x03, 0xb6, 0x12, 0x02
 642+ .byte 0x02, 0x35, 0x00
 643+ .byte 0x02, 0x26, 0x10
 644+ .byte 0x0c, 0xe0, 0x77, 0x52, 0x76, 0x53, 0x03, 0x03, 0x57, 0x42, 0x10, 0x18, 0x09
 645+ .byte 0x0c, 0xe1, 0x0d, 0x00, 0x23, 0x66, 0x0f, 0x15, 0x4d, 0x85, 0x08, 0x02, 0x10
 646+ .byte 0x0c, 0xe2, 0x39, 0x60, 0x77, 0x05, 0x03, 0x07, 0x96, 0x64, 0x0d, 0x1a, 0x0a
 647+ .byte 0x0c, 0xe3, 0x3f, 0x10, 0x16, 0x44, 0x0e, 0x04, 0x6c, 0x44, 0x04, 0x03, 0x0b
 648+ .byte 0x0c, 0xe4, 0x00, 0x61, 0x77, 0x04, 0x02, 0x04, 0x72, 0x32, 0x09, 0x19, 0x06
 649+ .byte 0x0c, 0xe5, 0x4f, 0x42, 0x27, 0x67, 0x0f, 0x02, 0x26, 0x33, 0x01, 0x03, 0x09
 650+ .byte 0x02, 0x36, 0x00
 651+ .byte 0x01, 0x11
 652+ .byte 0x01, 0x29
 653+ .byte 0x80
 654+lcd_sequence_d5:
 655+.byte 0x01, 0x01, 0x85, 0x01, 0x11, 0x01, 0x29, 0x80
 656+ .byte 0x02, 0xfe, 0x00
 657+ .byte 0x02, 0xc0, 0x01
 658+ .byte 0x02, 0xc1, 0x01
 659+ .byte 0x03, 0xc2, 0x03, 0x00
 660+ .byte 0x03, 0xc3, 0x01, 0x00
 661+ .byte 0x03, 0xc4, 0x03, 0x00
 662+ .byte 0x03, 0xc5, 0x34, 0x34
 663+ .byte 0x02, 0xc7, 0x00
 664+ .byte 0x03, 0xb1, 0x6d, 0x15
 665+ .byte 0x03, 0xb2, 0x6d, 0x15
 666+ .byte 0x03, 0xb3, 0x6d, 0x15
 667+ .byte 0x02, 0xb4, 0x03
 668+ .byte 0x03, 0xb6, 0x11, 0x02
 669+ .byte 0x02, 0x35, 0x00
 670+ .byte 0x02, 0x26, 0x10
 671+ .byte 0x0c, 0xe0, 0x23, 0x42, 0x20, 0x42, 0x0e, 0x01, 0xf5, 0xeb, 0x1e, 0x05, 0x18
 672+ .byte 0x0c, 0xe1, 0x5f, 0x22, 0x36, 0x21, 0x03, 0x1e, 0xfe, 0x7b, 0x02, 0x07, 0x18
 673+ .byte 0x0c, 0xe2, 0x5f, 0x34, 0x53, 0x77, 0x0a, 0x00, 0x70, 0xf4, 0x14, 0x06, 0x0f
 674+ .byte 0x0c, 0xe3, 0x0f, 0x23, 0x31, 0x54, 0x0f, 0x0b, 0x8e, 0x08, 0x00, 0x05, 0x15
 675+ .byte 0x0c, 0xe4, 0x5f, 0x33, 0x42, 0x14, 0x0e, 0x04, 0xa6, 0xf7, 0x0e, 0x00, 0x14
 676+ .byte 0x0c, 0xe5, 0x0c, 0x43, 0x44, 0x44, 0x0d, 0x0d, 0x7f, 0x39, 0x03, 0x02, 0x10
 677+ .byte 0x02, 0x3a, 0x66
 678+ .byte 0x02, 0x36, 0x00
 679+ .byte 0x01, 0x11
 680+ .byte 0x01, 0x29
 681+ .byte 0x80
 682+lcd_sequence_e6:
 683+.byte 0x01, 0x11, 0xf8, 0x01, 0x13, 0x01, 0x29, 0x80
 684+ .byte 0x01, 0x11
 685+ .byte 0xf8
 686+ .byte 0x02, 0xfe, 0x00
 687+ .byte 0x02, 0xef, 0x80
 688+ .byte 0x02, 0xc0, 0x13
 689+ .byte 0x02, 0xc1, 0x03
 690+ .byte 0x03, 0xc2, 0x12, 0x00
 691+ .byte 0x03, 0xc3, 0x12, 0x00
 692+ .byte 0x03, 0xc4, 0x12, 0x00
 693+ .byte 0x03, 0xc5, 0x2a, 0x3c
 694+ .byte 0x03, 0xb1, 0x6a, 0x15
 695+ .byte 0x03, 0xb2, 0x5f, 0x3f
 696+ .byte 0x03, 0xb3, 0x5f, 0x3f
 697+ .byte 0x02, 0xb4, 0x02
 698+ .byte 0x03, 0xb6, 0x12, 0x02
 699+ .byte 0x02, 0x35, 0x00
 700+ .byte 0x02, 0x26, 0x10
 701+ .byte 0x0c, 0xe0, 0x0f, 0x53, 0x45, 0x07, 0x00, 0x00, 0xb9, 0xf6, 0x08, 0x04, 0x18
 702+ .byte 0x0c, 0xe1, 0x00, 0x47, 0x55, 0x03, 0x0f, 0x08, 0x6f, 0x9b, 0x00, 0x18, 0x04
 703+ .byte 0x0c, 0xe2, 0x7e, 0x03, 0x54, 0x75, 0x00, 0x00, 0x3a, 0x52, 0x03, 0x02, 0x10
 704+ .byte 0x0c, 0xe3, 0x70, 0x55, 0x04, 0x73, 0x0e, 0x03, 0x25, 0xa3, 0x00, 0x10, 0x02
 705+ .byte 0x0c, 0xe4, 0x1a, 0x72, 0x33, 0x76, 0x00, 0x00, 0xeb, 0x97, 0x03, 0x05, 0x17
 706+ .byte 0x0c, 0xe5, 0x70, 0x36, 0x73, 0x12, 0x0a, 0x03, 0x79, 0xbe, 0x00, 0x17, 0x05
 707+ .byte 0x02, 0x3a, 0x06
 708+ .byte 0x01, 0x13
 709+ .byte 0x01, 0x29
 710+ .byte 0x80
 711+lcd_sequences_end:
 712+.endm
 713+
 714+ mov r0, #4
 715+ bl sendlcdc
 716+ bl readlcd
 717+ bl readlcd
 718+ bl readlcd
 719+ and r0, r0, #3
 720+ ldr r0, [sp,r0,lsl#2]
 721+ add sp, sp, r0
 722+lcdloop:
 723+ ldrb r1, [sp], #1
 724+ tst r1, #0x80
 725+ beq lcddata
 726+ bics r1, r1, #0x80
 727+ beq lcddone
 728+ mov r0, r1,lsl#10
 729+ bl udelay
 730+ b lcdloop
 731+lcddata:
 732+ ldrb r0, [sp], #1
 733+ bl sendlcdc
 734+lcdbyte:
 735+ subs r1, r1, #1
 736+ beq lcdloop
 737+ ldrb r0, [sp], #1
 738+ bl sendlcdd
 739+ b lcdbyte
 740+
 741+values1:
 742+ block0_constpool
 743+ block1_constpool
 744+ gpio_initdata
 745+ pmu_batch_1
 746+ pmu_batch_2
 747+ pmu_batch_3
 748+ pmu_batch_4
 749+ pmu_batch_5
 750+ block6_constpool
 751+ lcd_sequences
 752+
 753+ .align 1
 754+ .code 16
 755+thumb_nrv2e_d8:
 756+ mov r7,r2
 757+ mov r4,#1; neg r5,r4 @ r5= -1 initial condition
 758+ lsl r4,#31 @ 1<<31: refill next time
 759+ mov r6,#5
 760+ lsl r6,#8 @ 0x500 @ nrv2e M2_MAX_OFFSET
 761+ b top_n2e
 762+
 763+nrv2e_done:
 764+ blx execfirmware
 765+
 766+get1_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself]
 767+ ldrb r4,[r0] @ zero-extend next byte
 768+ adc r4,r4 @ double and insert CarryIn as low bit
 769+ add r0,#1
 770+ lsl r4,#24 @ move to top byte, and set CarryOut from old bit 8
 771+ mov pc,lr @ return, stay in current (THUMB) mode
 772+
 773+lit_n2e:
 774+ ldrb r3,[r0]; add r0,#1
 775+ strb r3,[r2]; add r2,#1
 776+top_n2e:
 777+ add r4,r4; mov lr,pc; beq get1_n2e; bcs lit_n2e
 778+ mov r1,#1; b getoff_n2e
 779+
 780+off_n2e:
 781+ sub r1,#1
 782+ add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1
 783+getoff_n2e:
 784+ add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1
 785+ add r4,r4; mov lr,pc; beq get1_n2e; bcc off_n2e
 786+
 787+ sub r3,r1,#3 @ set Carry
 788+ mov r1,#0 @ Carry unaffected
 789+ blo offprev_n2e @ r1 was 2; tests Carry only
 790+ lsl r3,#8
 791+ ldrb r5,[r0]; add r0,#1 @ low 7+1 r4
 792+ orr r5,r3
 793+ mvn r5,r5; beq nrv2e_done @ r5= ~r5
 794+ asr r5,#1; bcs lenlast_n2e
 795+ b lenmore_n2e
 796+
 797+offprev_n2e:
 798+ add r4,r4; mov lr,pc; beq get1_n2e; bcs lenlast_n2e
 799+lenmore_n2e:
 800+ mov r1,#1
 801+ add r4,r4; mov lr,pc; beq get1_n2e; bcs lenlast_n2e
 802+len_n2e:
 803+ add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1
 804+ add r4,r4; mov lr,pc; beq get1_n2e; bcc len_n2e
 805+ add r1,#6-2
 806+ b gotlen_n2e
 807+
 808+lenlast_n2e:
 809+ add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1 @ 0,1,2,3
 810+ add r1,#2
 811+gotlen_n2e: @ 'cmn': add the inputs, set condition codes, discard the sum
 812+ cmn r6,r5; bcs near_n2e @ within M2_MAX_OFFSET
 813+ add r1,#1 @ too far away, so minimum match length is 3
 814+near_n2e:
 815+ ldrb r3,[r2] @ force cacheline allocate
 816+copy_n2e:
 817+ ldrb r3,[r2,r5]
 818+ strb r3,[r2]; add r2,#1
 819+ sub r1,#1; bne copy_n2e
 820+ b top_n2e
 821+ .code 32
 822+
 823+font:
 824+ .byte 0, 0, 0, 0, 0
 825+ .byte 0, 0, 95, 0, 0
 826+ .byte 0, 7, 0, 7, 0
 827+ .byte 20, 127, 20, 127, 20
 828+ .byte 36, 42, 127, 42, 18
 829+ .byte 35, 19, 8, 100, 98
 830+ .byte 54, 73, 85, 34, 80
 831+ .byte 5, 3, 0, 0, 0
 832+ .byte 28, 34, 65, 0, 0
 833+ .byte 0, 0, 65, 34, 28
 834+ .byte 20, 8, 62, 8, 20
 835+ .byte 8, 8, 62, 8, 8
 836+ .byte 0, -96, 96, 0, 0
 837+ .byte 8, 8, 8, 8, 8
 838+ .byte 0, 96, 96, 0, 0
 839+ .byte 32, 16, 8, 4, 2
 840+ .byte 62, 81, 73, 69, 62
 841+ .byte 0, 66, 127, 64, 0
 842+ .byte 66, 97, 81, 73, 70
 843+ .byte 33, 65, 69, 75, 49
 844+ .byte 24, 20, 18, 127, 16
 845+ .byte 39, 69, 69, 69, 57
 846+ .byte 60, 74, 73, 73, 48
 847+ .byte 1, 113, 9, 5, 3
 848+ .byte 54, 73, 73, 73, 54
 849+ .byte 6, 73, 73, 41, 30
 850+ .byte 0, 54, 54, 0, 0
 851+ .byte 0, 86, 54, 0, 0
 852+ .byte 8, 20, 34, 65, 0
 853+ .byte 20, 20, 20, 20, 20
 854+ .byte 0, 65, 34, 20, 8
 855+ .byte 2, 1, 81, 9, 6
 856+ .byte 50, 73, 121, 65, 62
 857+ .byte 124, 18, 17, 18, 124
 858+ .byte 127, 73, 73, 73, 62
 859+ .byte 62, 65, 65, 65, 34
 860+ .byte 127, 65, 65, 34, 28
 861+ .byte 127, 73, 73, 73, 65
 862+ .byte 127, 9, 9, 9, 1
 863+ .byte 62, 65, 73, 73, 58
 864+ .byte 127, 8, 8, 8, 127
 865+ .byte 0, 65, 127, 65, 0
 866+ .byte 32, 64, 65, 63, 1
 867+ .byte 127, 8, 20, 34, 65
 868+ .byte 127, 64, 64, 64, 64
 869+ .byte 127, 2, 12, 2, 127
 870+ .byte 127, 4, 8, 16, 127
 871+ .byte 62, 65, 65, 65, 62
 872+ .byte 127, 9, 9, 9, 6
 873+ .byte 62, 65, 81, 33, 94
 874+ .byte 127, 9, 25, 41, 70
 875+ .byte 38, 73, 73, 73, 50
 876+ .byte 1, 1, 127, 1, 1
 877+ .byte 63, 64, 64, 64, 63
 878+ .byte 31, 32, 64, 32, 31
 879+ .byte 127, 32, 24, 32, 127
 880+ .byte 99, 20, 8, 20, 99
 881+ .byte 3, 4, 120, 4, 3
 882+ .byte 97, 81, 73, 69, 67
 883+ .byte 0, 127, 65, 65, 0
 884+ .byte 2, 4, 8, 16, 32
 885+ .byte 0, 65, 65, 127, 0
 886+ .byte 4, 2, 1, 2, 4
 887+ .byte 64, 64, 64, 64, 64
 888+ .byte 1, 2, 4, 0, 0
 889+ .byte 32, 84, 84, 84, 120
 890+ .byte 127, 68, 68, 68, 56
 891+ .byte 56, 68, 68, 68, 40
 892+ .byte 56, 68, 68, 68, 127
 893+ .byte 56, 84, 84, 84, 24
 894+ .byte 8, 126, 9, 1, 2
 895+ .byte 8, 84, 84, 84, 60
 896+ .byte 127, 4, 4, 4, 120
 897+ .byte 0, 68, 125, 64, 0
 898+ .byte 32, 64, 64, 61, 0
 899+ .byte 127, 16, 40, 68, 0
 900+ .byte 0, 65, 127, 64, 0
 901+ .byte 124, 4, 24, 4, 120
 902+ .byte 124, 8, 4, 4, 120
 903+ .byte 56, 68, 68, 68, 56
 904+ .byte 124, 20, 20, 20, 24
 905+ .byte 8, 20, 20, 20, 124
 906+ .byte 124, 8, 4, 4, 8
 907+ .byte 72, 84, 84, 84, 32
 908+ .byte 4, 63, 68, 64, 32
 909+ .byte 60, 64, 64, 32, 124
 910+ .byte 28, 32, 64, 32, 28
 911+ .byte 60, 64, 56, 64, 60
 912+ .byte 68, 40, 16, 40, 68
 913+ .byte 12, 80, 80, 80, 60
 914+ .byte 68, 100, 84, 76, 68
 915+ .byte 0, 8, 54, 65, 0
 916+ .byte 0, 0, 119, 0, 0
 917+ .byte 0, 65, 54, 8, 0
 918+ .byte 2, 1, 2, 4, 2
 919+
 920+errormessage:
 921+ .ascii "File not found!\0"
 922+
 923+bootfilename:
 924+ .ascii "emcore "
 925+
 926+text:
 927+ .ascii "emCORE Loader v"
 928+ .ascii VERSION
 929+ .ascii " r"
 930+ .ascii VERSION_SVN
 931+ .ascii "\0"
 932+ .ascii "Loading emCORE...\0"
 933+
 934+ .align 2
 935+
 936+execfirmware:
 937+ mcr p15, 0, r9,c7,c14,0 @ clean & invalidate data cache
 938+ bx r7
 939+
 940+ @ rendertext register map:
 941+ @ R0: Pointer to string, will be incremented
 942+ @ R1: Framebuffer address, will be incremented
 943+ @ R2: Color
 944+ @ R3: Trashed
 945+ @ R4: Trashed
 946+ @ R4: Trashed
 947+ @ R9: Set to 0
 948+ @ R14: Return address
 949+
 950+rendertext:
 951+ ldrb r3, [r0], #1
 952+ cmp r3, #0
 953+ moveq pc, lr
 954+ adr r5, font
 955+ sub r3, r3, #0x20
 956+ cmp r3, #0x5f
 957+ addcc r5, r3,lsl#2
 958+ addcc r5, r3
 959+ mov r3, #5
 960+rendertext_col:
 961+ mov r4, r1
 962+ ldrb r9, [r5], #1
 963+rendertext_row:
 964+ tst r9, #1
 965+ strneh r2, [r4]
 966+ add r4, r4, #480
 967+ movs r9, r9,lsr#1
 968+ bne rendertext_row
 969+ add r1, r1, #2
 970+ subs r3, r3, #1
 971+ bne rendertext_col
 972+ add r1, r1, #2
 973+ b rendertext
 974+
 975+lcd_mode:
 976+ .word 0x41100db8
 977+
 978+
 979+ @ Block 8 (DRAW) register map:
 980+ @ R0: Scratchpad
 981+ @ R1: Scratchpad
 982+ @ R2: Scratchpad
 983+ @ R3: Scratchpad
 984+ @ R4: Scratchpad
 985+ @ R5: Scratchpad
 986+ @ R6: Unused
 987+ @ R7: Unused
 988+ @ R8: LCD base address
 989+ @ R9: 0
 990+ @ R10: I2C base address
 991+ @ R11: TIMER base address
 992+ @ R12: SYSCON base address
 993+ @ R13: Scratchpad
 994+ @ R14: Return address / Scratchpad
 995+
 996+lcddone:
 997+ ldr r0, lcd_mode
 998+ str r0, [r8]
 999+ mov r1, #0x22000000
 1000+ orr r1, r1, #0x6800
 1001+ add r2, r1, #0x25800
 1002+ mov r0, #-1
 1003+fillbuff:
 1004+ str r0, [r2,#-4]!
 1005+ cmp r1, r2
 1006+ bne fillbuff
 1007+ mov sp, r1
 1008+ adr r0, text
 1009+ mov r2, #0
 1010+ bl rendertext
 1011+ add r1, sp, #0x1e00
 1012+printerror:
 1013+ bl rendertext
 1014+ mcr p15, 0, r9,c7,c10,0 @ clean data cache
 1015+ mcr p15, 0, r9,c7,c10,4 @ drain write buffer
 1016+ mov r0, #0x2a
 1017+ bl sendlcdc
 1018+ mov r0, #0
 1019+ bl sendlcdd
 1020+ mov r0, #0xef
 1021+ bl sendlcdd
 1022+ mov r0, #0x2b
 1023+ bl sendlcdc
 1024+ mov r0, #0
 1025+ bl sendlcdd
 1026+ mov r0, #0x200
 1027+ orr r0, r0, #0x3f
 1028+ bl sendlcdd
 1029+ mov r0, #0x2c
 1030+ bl sendlcdc
 1031+blit:
 1032+ sub lr, r8, #0x00100000
 1033+ mov sp, #1
 1034+ str sp, [lr,#0x30]
 1035+ mov sp, #0x22000000
 1036+ orr sp, sp, #0x2d000
 1037+ add lr, lr, #0x100
 1038+ mov r4, #0x8800
 1039+ orr r4, r4, #0xc1
 1040+ ldmia sp, {r0-r3}
 1041+ stmia lr, {r0-r4}
 1042+@ tst r5, #0xff
 1043+@failed:
 1044+@ bne failed
 1045+ mov r0, #0x30
 1046+ mov r1, #120
 1047+ bl pmuwrite
 1048+ mov r0, #0x31
 1049+ mov r1, #1
 1050+ bl pmuwrite
 1051+
 1052+
 1053+hang: b hang
 1054+
 1055+ @ udelay register map:
 1056+ @ R0: Microseconds
 1057+ @ R1: Trashed
 1058+ @ R11: TIMER base address
 1059+ @ R14: Return address
 1060+
 1061+udelay:
 1062+ ldr r1, [r11,#0xb4]
 1063+ add r0, r0, r1
 1064+udelayloop:
 1065+ ldr r1, [r11,#0xb4]
 1066+ cmp r1, r0
 1067+ bmi udelayloop
 1068+ mov pc, lr
 1069+
 1070+ @ i2cwaitrdy register map:
 1071+ @ R9: Set to 0
 1072+ @ R10: I2C base address
 1073+ @ R14: Return address
 1074+
 1075+i2cwaitrdy:
 1076+ ldr r9, [r10,#0x10]
 1077+ cmp r9, #0
 1078+ bne i2cwaitrdy
 1079+ mov pc, lr
 1080+
 1081+ @ i2cwait register map:
 1082+ @ R3: Set to 0x10
 1083+ @ R10: I2C base address
 1084+ @ R14: Return address
 1085+
 1086+i2cwait:
 1087+ ldr r3, [r10]
 1088+ ands r3, #0x10
 1089+ beq i2cwait
 1090+ mov pc, lr
 1091+
 1092+ @ pmuwrite register map:
 1093+ @ R0: Address
 1094+ @ R1: Data
 1095+ @ R2: Set to 0xb7
 1096+ @ R3: Set to 0x10
 1097+ @ R4: Return address backup
 1098+ @ R10: I2C base address
 1099+ @ R14: Return address / Scratchpad
 1100+
 1101+pmuwrite:
 1102+ mov r4, lr
 1103+ mov lr, #0xe6
 1104+ str lr, [r10,#0x0c]
 1105+ mov lr, #0xf0
 1106+ str lr, [r10,#0x04]
 1107+ mov r2, #0xb7
 1108+ str r2, [r10]
 1109+ bl i2cwait
 1110+ str r0, [r10,#0x0c]
 1111+ str r2, [r10]
 1112+ bl i2cwait
 1113+ str r1, [r10,#0x0c]
 1114+ str r2, [r10]
 1115+ bl i2cwait
 1116+ mov lr, #0xd0
 1117+ str lr, [r10,#0x04]
 1118+ str r2, [r10]
 1119+pmuwrite_wait:
 1120+ ldr lr, [r10,#0x04]
 1121+ tst lr, #0x20
 1122+ bne pmuwrite_wait
 1123+ mov pc, r4
 1124+
 1125+ @ pmuread register map:
 1126+ @ R0: Address
 1127+ @ R1: Data
 1128+ @ R2: Set to 0xb7
 1129+ @ R3: Set to 0x10
 1130+ @ R4: Return address backup
 1131+ @ R10: I2C base address
 1132+ @ R14: Return address / Scratchpad
 1133+
 1134+pmuread:
 1135+ mov r4, lr
 1136+ mov lr, #0xe6
 1137+ str lr, [r10,#0x0c]
 1138+ mov lr, #0xf0
 1139+ str lr, [r10,#0x04]
 1140+ mov r2, #0xb7
 1141+ str r2, [r10]
 1142+ bl i2cwait
 1143+ str r0, [r10,#0x0c]
 1144+ str r2, [r10]
 1145+ bl i2cwait
 1146+ mov r1, #0xe7
 1147+ str r1, [r10,#0x0c]
 1148+ mov r1, #0xb0
 1149+ str r1, [r10,#0x04]
 1150+ str r2, [r10]
 1151+ bl i2cwait
 1152+ mov r1, #0x37
 1153+ str r1, [r10]
 1154+ bl i2cwait
 1155+ ldr r1, [r10,#0x0c]
 1156+ mov lr, #0x90
 1157+ str lr, [r10,#0x04]
 1158+ str r2, [r10]
 1159+pmuread_wait:
 1160+ ldr lr, [r10,#0x04]
 1161+ tst lr, #0x20
 1162+ bne pmuread_wait
 1163+ mov pc, r4
 1164+
 1165+ @ pmubatch register map:
 1166+ @ R0: Scratchpad
 1167+ @ R1: Scratchpad
 1168+ @ R2: Set to 0xb7
 1169+ @ R3: Set to 0x10
 1170+ @ R4: Inner return address backup
 1171+ @ R7: Outer return address backup
 1172+ @ R9: Number of address-data pairs to be sent (must be >0), will be reset to 0
 1173+ @ R10: I2C base address
 1174+ @ R13: Address-data pair list pointer (will be incremented)
 1175+ @ R14: Return address / Scratchpad
 1176+
 1177+pmubatch:
 1178+ mov r7, lr
 1179+pmubatch_loop:
 1180+ ldrb r0, [sp], #1
 1181+ ldrb r1, [sp], #1
 1182+ bl pmuwrite
 1183+ subs r9, r9, #1
 1184+ bne pmubatch_loop
 1185+ mov pc, r7
 1186+
 1187+ @ sendlcdc register map:
 1188+ @ R0: Command to be sent
 1189+ @ R8: LCD base address
 1190+ @ R9: Will be set to 0
 1191+ @ R14: Return address
 1192+
 1193+sendlcdc:
 1194+ ldr r9, [r8,#0x1c]
 1195+ ands r9, r9, #0x10
 1196+ bne sendlcdc
 1197+ str r0, [r8,#0x04]
 1198+ mov pc, lr
 1199+
 1200+ @ sendlcdd register map:
 1201+ @ R0: Data to be sent
 1202+ @ R8: LCD base address
 1203+ @ R9: Will be set to 0
 1204+ @ R14: Return address
 1205+
 1206+sendlcdd:
 1207+ ldr r9, [r8,#0x1c]
 1208+ ands r9, r9, #0x10
 1209+ bne sendlcdd
 1210+ str r0, [r8,#0x40]
 1211+ mov pc, lr
 1212+
 1213+ @ readlcd register map:
 1214+ @ R0: Result data
 1215+ @ R8: LCD base address
 1216+ @ R14: Return address
 1217+
 1218+readlcd:
 1219+ ldr r0, [r8,#0x1c]
 1220+ tst r0, #2
 1221+ beq readlcd
 1222+ str r0, [r8,#0x10]
 1223+readlcd_wait:
 1224+ ldr r0, [r8,#0x1c]
 1225+ tst r0, #0x1
 1226+ beq readlcd_wait
 1227+ ldr r0, [r8,#0x14]
 1228+ mov r0, r0,lsr#1
 1229+ mov pc, lr
Index: emcore/trunk/loader/ipodnano4g/version.h
@@ -0,0 +1,36 @@
 2+//
 3+//
 4+// Copyright 2010 TheSeven
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __VERSION_H__
 26+#define __VERSION_H__
 27+
 28+
 29+#define VERSION "0.0.1"
 30+#define VERSION_MAJOR 0
 31+#define VERSION_MINOR 0
 32+#define VERSION_PATCH 1
 33+#define VERSION_SVN "$REVISION$"
 34+#define VERSION_SVN_INT $REVISIONINT$
 35+
 36+
 37+#endif
Index: emcore/trunk/loader/ipodnano4g/Makefile
@@ -0,0 +1,101 @@
 2+NAME := emcoreldr-ipodnano4g
 3+
 4+EMCOREDIR ?= ../../
 5+
 6+ifeq ($(shell uname),WindowsNT)
 7+CCACHE :=
 8+else
 9+CCACHE := $(shell which ccache)
 10+endif
 11+
 12+CROSS ?= arm-elf-eabi-
 13+CC := $(CCACHE) $(CROSS)gcc
 14+AS := $(CROSS)as
 15+LD := $(CROSS)ld
 16+OBJCOPY := $(CROSS)objcopy
 17+UCLPACK := ucl2e10singleblk
 18+
 19+CFLAGS += -Os -fno-pie -fno-stack-protector -fomit-frame-pointer -I. -ffunction-sections -fdata-sections -mcpu=arm1176jz-s
 20+LDFLAGS += "$(shell $(CC) -print-libgcc-file-name)" --gc-sections
 21+
 22+preprocess = $(shell $(CC) $(PPCFLAGS) $(2) -E -P -x c $(1) | grep -v "^\#")
 23+preprocesspaths = $(shell $(CC) $(PPCFLAGS) $(2) -E -P -x c $(1) | grep -v "^\#" | sed -e "s:^..*:$(dir $(1))&:" | sed -e "s:^\\./::")
 24+
 25+REVISION := $(shell svnversion .)
 26+REVISIONINT := $(shell echo $(REVISION) | sed -e "s/[^0-9].*$$//")
 27+
 28+SRC := $(call preprocesspaths,SOURCES,-I. -I..)
 29+OBJ := $(SRC:%.c=build/%.o)
 30+OBJ := $(OBJ:%.S=build/%.o) $(HELPERS)
 31+
 32+all: $(NAME)
 33+
 34+-include $(OBJ:%=%.dep)
 35+
 36+$(NAME): build/$(NAME).bin
 37+
 38+build/$(NAME).bin: build/$(NAME).elf
 39+ @echo [OC] $<
 40+ @$(OBJCOPY) -O binary $^ $@
 41+
 42+build/$(NAME).elf: ls.x $(OBJ)
 43+ @echo [LD] $@
 44+ @$(LD) $(LDFLAGS) -o $@ -T ls.x $(OBJ)
 45+
 46+build/%.o: %.c build/version.h
 47+ @echo [CC] $<
 48+ifeq ($(shell uname),WindowsNT)
 49+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 50+else
 51+ @-mkdir -p $(dir $@)
 52+endif
 53+ @$(CC) -c $(CFLAGS) -o $@ $<
 54+ @$(CC) -MM $(CFLAGS) $< > $@.dep.tmp
 55+ @sed -e "s|.*:|$@:|" < $@.dep.tmp > $@.dep
 56+ifeq ($(shell uname),WindowsNT)
 57+ @sed -e "s/.*://" -e "s/\\$$//" < $@.dep.tmp | fmt -1 | sed -e "s/^ *//" -e "s/$$/:/" >> $@.dep
 58+else
 59+ @sed -e 's/.*://' -e 's/\\$$//' < $@.dep.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $@.dep
 60+endif
 61+ @rm -f $@.dep.tmp
 62+
 63+build/%.o: %.S build/version.h
 64+ @echo [CC] $<
 65+ifeq ($(shell uname),WindowsNT)
 66+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 67+else
 68+ @-mkdir -p $(dir $@)
 69+endif
 70+ @$(CC) -c $(CFLAGS) -o $@ $<
 71+ @$(CC) -MM $(CFLAGS) $< > $@.dep.tmp
 72+ @sed -e "s|.*:|$@:|" < $@.dep.tmp > $@.dep
 73+ifeq ($(shell uname),WindowsNT)
 74+ @sed -e "s/.*://" -e "s/\\$$//" < $@.dep.tmp | fmt -1 | sed -e "s/^ *//" -e "s/$$/:/" >> $@.dep
 75+else
 76+ @sed -e 's/.*://' -e 's/\\$$//' < $@.dep.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $@.dep
 77+endif
 78+ @rm -f $@.dep.tmp
 79+
 80+build/__emcore_%.o: $(EMCOREDIR)/export/%.S
 81+ @echo [CC] $<
 82+ifeq ($(shell uname),WindowsNT)
 83+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 84+else
 85+ @-mkdir -p $(dir $@)
 86+endif
 87+ @$(CC) -c $(CFLAGS) -o $@ $<
 88+
 89+build/version.h: version.h .svn/entries
 90+ @echo [PP] $<
 91+ifeq ($(shell uname),WindowsNT)
 92+ @-if not exist build md build
 93+ @sed -e "s/\$$REVISION\$$/$(REVISION)/" -e "s/\$$REVISIONINT\$$/$(REVISIONINT)/" < $< > $@
 94+else
 95+ @-mkdir -p build
 96+ @sed -e 's/\$$REVISION\$$/$(REVISION)/' -e 's/\$$REVISIONINT\$$/$(REVISIONINT)/' < $< > $@
 97+endif
 98+
 99+clean:
 100+ @rm -rf build
 101+
 102+.PHONY: all clean $(NAME)