Commit c3d9625b authored by Neil Turton's avatar Neil Turton
Browse files

Import from SrcFiler

parent 3629688c
This diff is collapsed.
......@@ -23,28 +23,29 @@
; 15-May-90 ArtG Added ReadyByte : improves synchronization
; when ExtCmd execution toggles A21/A22.
; 18-Jun-90 ArtG Added CPR15 read/write functions
;
;
; 04-Oct-96 JRH Updated comments to refer to test box on A23.
; Added support for speaking to the test box when
; running from the 2nd ROM bank, conditioned on
; CanLiveOnROMCard. Needed because 2nd ROM bank
; isn't ghosted on the A23 line like the 1st bank.
;------------------------------------------------------------------------
SUBT Test adapter interface
;
; The test adapter senses an access to the ROM with address line A21 high.
; Current (2M addressing space) ROMs only use address lines A2 to A20,
; so if A21 to A22 are asserted they will be ignored (the ROMS are aliased
; into 8M of space). With no test adapter, the aliased ROM location will
; The test adapter senses an access to the ROM with address line A23 high.
; Current (8M addressing space) ROMs only use address lines A2 to A22,
; so if A23 is asserted it will be ignored (the ROMS are aliased
; into 16M of space). With no test adapter, the aliased ROM location will
; be read and may be recognised. The test adapter may selectively disable
; ROMs when A21 is high, causing arbitrary data to be read. This data
; ROMs when A23 is high, causing arbitrary data to be read. This data
; should be dependent on the previous ROM read operation, and will
; therefore be predictably not equal to the data read when the ROMs are
; aliased.
; The assumption that A21 is unused may be invalidated by a later issue
; of the PCB. A22 is therefore asserted at the same time : this will then
; be used on a PCB where A22 is tracked to a test connector and 8Mbit ROMS
; are used. Machines using larger ROMs than 8 Mbit (4M addressing space)
; will require explicit decoding or a new communication scheme.
; The assumption that A23 is unused may be invalidated by a later issue
; of the PCB. Machines using larger ROMs than 8Mbytes will require explicit
; decoding or a new communication scheme.
;
......@@ -82,7 +83,7 @@ ts_GetCommand ROUT
;
; Load up the registers for the test interface communication -
;
[ :LNOT: CanLiveOnROMCard
LDR r0,%01 ; set zero in r0
ADD pc,pc,r0 ;(generally useful constant - especially for skip)
01
......@@ -98,7 +99,22 @@ ts_GetCommand ROUT
ADDS r2,pc,r2 ; adjust r2 for ROM-relative address
ADDS r4,r0,r0 ; clear output accumulator
04 ; where pc is when added to r2
|
; Point r2 at a word which contains 0 in 0-8MB physical space.
; Note that this code doesn't cope with the case where it can't find a zero
; word anywhere in the whole ROM. I don't think that this is a problem.
MOV r0, #0 ; expected below
MOV r2, #0 ; start of physical space
01
LDR r1, [r2, #4]!
TEQ r1, r0 ; is it zero?
BNE %01
ADD r2, r2, #ts_Alias_bits ; point to zero word in ghost
MOV r1, #-1 ; expected below
04
]
; do an RD operation (four strobes) to ensure interface cleared
LDR r3,[r2]
......@@ -613,7 +629,7 @@ ts_PosText ROUT
;
ts_SendLCDCmd
[ :LNOT: CanLiveOnROMCard
LDR r0,%01 ; set zero in r0
ADD pc,pc,r0
01
......@@ -629,7 +645,23 @@ ts_SendLCDCmd
ADDS r2,pc,r2 ; adjust r2 for ROM-relative address
ADDS r0,r0,r0 ; dummy (to keep labels nearby !)
04 ; where pc points when added to r2
|
; Point r2 at a word which contains 0 in 0-8MB physical space.
; If this word still reads as 0 when its ghost/alias is read from 8-16MB space
; (A23 set) then we don't have a test box, otherwise we do.
; Note that this code doesn't cope with the case where it can't find a zero
; word anywhere in the whole ROM. I don't think that this is a problem.
MOV r0, #0 ; ts_send_command_byte expects r0=0
MOV r2, #0 ; start of physical space
01
LDR r1, [r2, #4]!
TEQ r1, r0 ; is it zero?
BNE %01
ADD r2, r2, #ts_Alias_bits ; point to zero word in ghost
04
]
; Wait - gap between successive WS attempts or successive bytes
......
; > InitModule
; Source for Pre_InitModule, PostInitModule im_InitModules & im_Pre_InitPodMod functions
;
; ***********************************
; *** C h a n g e L i s t ***
; ***********************************
;
; Date Who Version Description
; ---- --- ------- -----------
; 13-Jun-96 BAR 0.01 Started
; 27-Jun-96 BAR 0.02 Added code to check the type of reset we
; just had. If power-on then we can display
; messages, else exit back.
;
;
; Provides functions to display messages for when we initiliseing the
; modules. Messages are only sent to the display adapator, if the Reset Type
; is Power On Reset. The code uses the constant ResetType, defined in
; kernel.hdr.KernelWS. This is the address of a memory location, where the
; type of reset is stored. ResetType is a sigle bit flag, in bit 0 of the
; memory location. The constant PowerOnReset is used, which is defined in
; Kernel.s.newReset. This defines the value that a power-on reset should be.
; The value of PowerOnReset should always be 1. (This corresponds to the
; value of the bit 4 of IOMD's IRQA Status register, where the Power-on
; reset status is initially stored.) The value of ResetType can vary between
; different versions of the operating system.
;
;
; im_Pre_InitModule is called before a module is started
; im_Post_InitModule is called after a module is started, only if there was
; an error
; im_InitModules is called at the start of initiliseing the modules.
; im_Pre_InitPodMod is called when we start the podule manager.
;
; All the functions will push registers r0-r12 to the stack, check the
; poweron reset status, if power on reset, then send a message to the
; display adaptor and then pull them off at the end.
;
;
im_Pre_InitModule ROUT
Push "r0-r12" ; Put r0->r12 on to stack
; Get the type of reset we had, if power-on - can use display adaptor
LDR r1,=ResetType ; Load r1 with address of ResetType
LDR r0,[r1] ; Get contents of ResetType = what type of reset
CMPS r0,#PowerOnReset ; Compare with PowerOnReset (1)
;if equel send message
LDREQ r4,[r11,#ROMModule_Name] ; Put ptr to mod name in r4
BLEQ ts_SendText ; Send the txt to disp adaptor
;restore the reg's.
Pull "r0-r12" ; Get r0->r12 from the stack
MOV pc,r14 ; Return to caller
im_Post_InitModule ROUT
1
= "Module Bad",0
Push "r0-r12" ; Put r0->r12 on to stack
; Get the type of reset we had, if power-on - can use display adaptor
LDR r1,=ResetType ; Load r1 with address of ResetType
LDR r0,[r1] ; Get contents of ResetType = what type of reset
CMPS r0,#PowerOnReset ; Compare with PowerOnReset (1)
BNE %FT2 ; IF not equal jump to 2 AKA don't send msg.
Push "r0" ; Put r0 in stack again
ADR r4, %BT1 ; r4 = bad module msg
BL ts_SendText ; Send the txt to disp adaptor
Pull "r0" ; Get r0 from the stack
ADDVC r4,r0,#4 ; If V Clr add 4 to r0 - point to err txt
BLVC ts_SendText ; Send the txt to disp adaptor
2
Pull "r0-r12" ; Get r0->r12 from the stack
MOV pc,r14 ; Return to caller
im_InitModules ROUT
1
= "Init Modules :",0
Push "r0-r12" ; Put r0->r12 on to stack
; Get the type of reset we had, if power-on - can use display adaptor
LDR r1,=ResetType ; Load r1 with address of ResetType
LDR r0,[r1] ; Get contents of ResetType = what type of reset
CMPS r0,#PowerOnReset ; Compare with PowerOnReset (1)
;if equel send message
ADREQ r4, %BT1 ; r4 = init msg
BLEQ ts_SendText ; Send the txt to disp adaptor
;restore the reg's.
Pull "r0-r12" ; Get r0->r12 from the stack
MOV pc,r14 ; Return to caller
im_Pre_InitPodMod ROUT
1
= "Podule",0
Push "r0-r12" ; Put r0->r12 on to stack
; Get the type of reset we had, if power-on - can use display adaptor
LDR r1,=ResetType ; Load r1 with address of ResetType
LDR r0,[r1] ; Get contents of ResetType = what type of reset
CMPS r0,#PowerOnReset ; Compare with PowerOnReset (1)
;if equel send message
ADREQ r4, %BT1 ; r4 = init msg
BLEQ ts_SendText ; Send the txt to disp adaptor
;restore the reg's.
Pull "r0-r12" ; Get r0->r12 from the stack
MOV pc,r14 ; Return to caller
END
......@@ -3,7 +3,7 @@
TTL RISC OS 2+ POST IO controller
;
; This initial IOC test simply reports the content of the IRQ and FIRQ
; registers, to show any unexpected pending IRQs.
; registers, to show any unexpected pending IRQs.
; Certain of these should really be cleared, and the effect of an
; interrupt tested.
;
......@@ -16,27 +16,31 @@
; 29-Nov-91 ArtG Added IOC bus test using mask registers
; 20-Jun-93 ArtG Modified for 29-bit IOMD test
; 18-Nov-94 RCM Morris changes
; 15-May-96 BAR Changes for 7500FE - new IOMD ID code.
; Now list 3 ID codes.
; 17-Jun-96 BAR Change ts_IOMD_IDn definitions to point to
; definitions in IOMDL
; 09-Jul-96 BAR Improve IOMD ID code.
;
;
;------------------------------------------------------------------------
[ IO_Type = "IOMD"
[ IO_Type = "IOMD"
ts_IObase * IOMD_Base
ts_IOmask * &00fffff0 ;&1fffffff
ts_IOreg1 * IOMD_VIDEND ;IOMD_VIDCUR
ts_IOreg2 * IOMD_VIDSTART
ts_IObswap * 32
ts_IOMD_ID * &D4E7
[ MorrisSupport
ts_IOMD_IDmorris * &5B98
]
|
ts_IOMD_ID1 * IOMD_Original
ts_IOMD_ID2 * IOMD_7500
ts_IOMD_ID3 * IOMD_7500FE
|
ts_IObase * IOC
ts_IOmask * &ff0000
ts_IOreg1 * IOCIRQMSKA
ts_IOreg2 * IOCIRQMSKB
ts_IObswap * 16
]
]
ts_IOCreg
MOV r0,#0 ; zero error accumulator
......@@ -64,27 +68,31 @@ ts_IOCreg
LDR r8, =ts_IOmask
ANDS r8, r0, r8
MOV pc,r14 ; return error if any bit failed
MOV pc,r14 ; return error if any bit failed
ts_IOCstat
LDR r3, =ts_IObase
MOV r0,#0
[ IO_Type = "IOMD"
LDRB r1,[r3,#IOMD_ID1]
ORR r0,r0,r1, LSL #(32-24)
LDRB r1,[r3,#IOMD_ID0]
ORR r0,r0,r1
LDR r1,=ts_IOMD_ID
CMPS r0,r1 ; check IOMD identity
[ MorrisSupport
LDRNE r1,=ts_IOMD_IDmorris ; allow for Morris variant
CMPNES r0,r1
]
MOV r0,r0,LSL #16
LDRB r1,[r3,#IOMD_VERSION]
ORR r8,r0,r1, LSL #12
MOV pc,r14
|
LDR r3, =ts_IObase ; r3 points to IO Chip base address
MOV r0,#0 ; clear r0
[ IO_Type = "IOMD"
; Check IOMD chip variants
LDRB r1,[r3,#IOMD_ID1] ; load r1 with IOMD ID high byte
LDRB r0,[r3,#IOMD_ID0] ; load r1 with IOMD ID low byte
ORR r0,r0,r1, LSL #8 ; Or r0 and r1 - shifted left 8, put in r0
LDR r1,=ts_IOMD_ID1 ; get Ref IOMD ID code #1
CMPS r0,r1 ; check =to IOMD ID Code #1
LDRNE r1,=ts_IOMD_ID2 ; If not ID1, get Ref IOMD ID code #2
CMPNES r0,r1 ; If not ID1, check =to IOMD ID Code #2
LDRNE r1,=ts_IOMD_ID3 ; if not ID1 and ID2, get Ref IOMD ID code #3
CMPNES r0,r1 ; If not ID1 and ID2, check =to IOMD ID Code #3
MOV r0,r0,LSL #16 ; Move ID code in to top 16 bits
LDRB r1,[r3,#IOMD_VERSION] ; Load r with IOMD Version number
ORR r8,r0,r1, LSL #12 ; Or r0 and r1 - shifted left 12, put in r8
MOV pc,r14 ; extit to whence came from.
|
; Check IOC chip variants
LDRB r1,[r3,#IOCControl]
ORR r0,r0,r1, LSL #(32 - 8)
LDRB r1,[r3,#IOCIRQSTAA]
......@@ -96,7 +104,7 @@ ts_IOCstat
ANDS r1,r1,#0 ; return zero flag (OK)
MOV pc,r14
]
]
END
END
; > LEDDelay
; Source for LEDDelay function
;
; ***********************************
; *** C h a n g e L i s t ***
; ***********************************
;
; Date Who Version Description
; ---- --- ------- -----------
; 30-May-96 BAR 0.01 Started
;
; Will provide a 1/4 second delay for flashing the LED's
ld_quarter_sec * (35000*8) ; 1/4 Second delay !
ld_LED_Delay ROUT
; Generate the required delay between changing the LED status
; On entry ....
; r4 = required delay time
; Register usage ....
; r0, general scratch pad
;
01 LDR r0,=ld_quarter_sec ; Load r0 with 1/4 seconds delay
02 SUBS r0,r0,#1 ; subtract one
BNE %02 ; back we go .... pause for a 1/4 second
SUBS r4,r4,#1 ; subtract one
BNE %01 ; repeat the pause for the flash duration
MOV pc,r14 ; Return to caller
END
......@@ -13,7 +13,13 @@
; ---- ---- -------
; 1-Jun-93 ArtG Derived from Mem1 for use on Medusa
; 18-Nov-94 RCM Morris changes
;
; 24-Jun-96 BAR Change the IOMD ID code checking code,
; instead of checking for ARM7500 and skipping
; ARM7500 specifi code if not equal, not
; checks for original (RriscPC) IOM ID code
; and skip if equal, thus ARM7500 and
; ARM7500FE parts still do correct test.
; 08-Jul-96 BAR Ensure r0 is cleared before checking IOMD vsn no.
;
;------------------------------------------------------------------------
......@@ -40,17 +46,25 @@
ts_LineTest
[ MorrisSupport
MOV r12, #IOMD_Base
LDRB r0, [r12, #IOMD_ID0]
CMP r0, #&98
LDRB r0, [r12, #IOMD_ID1]
CMPEQ r0, #&5B
BNE ts_LineTestIOMD ; NOT MORRIS assume Medusa hardware
MOV r0,#0 ; Clear out r0
LDRB r1,[r12,#IOMD_ID1] ; load r1 with IOMD ID high byte
ORR r0,r0,r1, LSL #8 ; Or r0 and r1 - shifted left 8, put in r0
LDRB r1,[r12,#IOMD_ID0] ; load r1 with IOMD ID low byte
ORR r0,r0,r1 ; Or r0 and r1, put in r0
LDR r1,=ts_IOMD_ID1 ; get Ref IOMD ID code #1 (Original)
CMPS r0,r1 ; check for IOMD ID Code #1
BEQ ts_LineTestIOMD ; Original IOMD, not 7500 or 7500FE, assume RiscPC hardware
;
; ts_LineTest for Morris
; Here bceause its an ARM7500 or ARM7500 'FE' variant : Morris H/W
;
MOV r11, #IOMD_DRAMWID_DRAM_32bit * &0F ;set all 4 banks to be 32bit initially
LDR r1, =ts_IOMD_ID3
TEQ r0, r1 ; are we on FE part?
ORREQ r11, r11, #IOMD_DRAMWID_EDO_Enable :OR: IOMD_DRAMWID_RASCAS_3 :OR: IOMD_DRAMWID_RASPre_4
; if so, then enable EDO and slower RASCAS and RASPre times
; ts_LineTest for Morris
;
MOV r14, #IOMD_Base
STRB r11, [r14, #IOMD_DRAMWID]
MOV r0,#MMUC_D ; enable 32-bit addressing of data
......@@ -226,7 +240,7 @@ ts_LineTest
; If the RAM found still seems OK, add it's size into the r10 accumulator
; Working or not, carry on to check the next bank.
ADD r10,r10,r13 ; accumulate DRAM if any found
ADD r10,r10,r13 ; accumulate DRAM if any found
ADD r12, r12, #DRAM1PhysRam-DRAM0PhysRam ; move onto next bank
MOV r9, r9, LSL #1 ; shunt up position in DRAMWID
CMP r9, #&0010 ; if more banks to do
......@@ -283,10 +297,10 @@ ts_LineTestIOMD
22
ADR r4,%BT5 ; Add size (in hex Mbyte)
MOV r8,r9, LSL #24 ; to "VRam : " message
BL ts_MoreText
BL ts_MoreText
; Worked out what size VRAM is, and set up IOMD register.
; Do a data line test on the resulting array, repeated at oddword address to
; Worked out what size VRAM is, and set up IOMD register.
; Do a data line test on the resulting array, repeated at oddword address to
; ensure both banks get tested with walking 0 and walking 1
ADR r4,%BT4
......@@ -443,7 +457,7 @@ ts_LineTestIOMD
; If the RAM found still seems OK, add it's size into the r10 accumulator
; Working or not, carry on to check the next bank.
ADD r10,r10,r13 ; accumulate DRAM if any found
ADD r10,r10,r13 ; accumulate DRAM if any found
ADD r12, r12, #DRAM1PhysRam-DRAM0PhysRam ; move onto next bank
MOV r9, r9, LSL #2 ; shunt up position in DRAMCR
CMP r9, #&100 ; if more banks to do
......@@ -510,7 +524,7 @@ ts_Dataline ROUT
;
10 MOV r6,r1 ; set pointer for a write loop
MOV r5,#1 ; set initial test pattern
MVN r4,r5 ; and it's inverse
MVN r4,r5 ; and it's inverse
11
STMIA r6!,{r4-r5} ; write the patterns
......@@ -522,7 +536,7 @@ ts_Dataline ROUT
;
MOV r6,r1 ; set pointer for a read loop
MOV r5,#1 ; set initial test pattern
MVN r4,r5 ; and it's inverse
MVN r4,r5 ; and it's inverse
MOV r0,#0 ; accumulate result
21
LDMIA r6!,{r2-r3} ; read the patterns
......@@ -537,7 +551,7 @@ ts_Dataline ROUT
;
; After all checks at this address group, report back errors
;
MOVS r0,r0 ; check for any result bits set
MOVS r0,r0 ; check for any result bits set
MOV pc,r14 ; return r0 with error map (or 0)
......@@ -555,7 +569,7 @@ ts_Dataline ROUT
;
; It works something like :
;
; MaxRam = PhysRam | (Memory size - 4);
; MaxRam = PhysRam | (Memory size - 4);
; for (pattern = 4; pattern < memsize; pattern <<= 1 )
; *(PhysRam ^ pattern) = pattern;
; *(MaxRam ^ pattern) = ~pattern;
......@@ -658,7 +672,7 @@ ts_Byteword ROUT
STRB r2,[r1,r2] ; write byte (0, 1, 2 or 3)
MOV r4,r2,LSL #3 ; calculate expected result
MOV r5,#&ff
MOV r5,#&ff
MVN r5,r5,LSL r4
AND r5,r5,r3 ; word signature, byte removed
ORR r5,r5,r2,LSL r4 ; byte signature inserted
......@@ -673,7 +687,7 @@ ts_Byteword ROUT
; Loop for next byte
;
ADD r2,r2,#1 ; Bump byte counter
CMPS r2,#4 ; ... until 4 byte strobes tested
CMPS r2,#4 ; ... until 4 byte strobes tested
BLO %BT02
;
; byte strobes all tested : check for errors
......@@ -687,5 +701,4 @@ ts_Byteword ROUT
ts_endline
END
\ No newline at end of file
END
......@@ -6,6 +6,8 @@
; 24.04.90 0.10 ArtG Added ROM size test
; 15.05.90 1.00 ArtG Changed to put checksum at (end - 2 words)
; 17.05.90 1.01 ArtG Changed to get ROM length from vectot table
; 16-Aug-96 1.02 JRH Gets ROM start using PC-relative addressing,
; to support OSimages in 1st or 2nd ROM bank
;
;
; This file will perform quick checksum test on the OS ROMS.
......@@ -37,7 +39,8 @@ ts_CRCsize * (2 * 4)
ts_ROM_checksum
MOV r1, #&00 ; initialise accumulator
LDR r0, =PhysROM ; initialise pointer
ADRL r0, ROM ; initialise pointer using PC-relative
; addressing (could be 1st or 2nd bank)
LDR r2, [r0, #ts_ROMSIZE] ; initialise endstop
ADD r2, r2, r0 ; - must be at least 8 words
SUB r2, r2, #(10 * 4) ; below the real endpoint
......@@ -93,7 +96,8 @@ loop1 LDMIA r0!, {r4 - r11} ;LOAD r4 TO r11 WITH THE CONTENTS
ts_ROM_alias ROUT
MOV r0,#PhysROM ; get some words from ROM start
ADRL r0, ROM ; initialise pointer using PC-relative
; addressing (could be 1st or 2nd bank)
LDR r3,[r0, #ts_ROMSIZE] ; get the ROM length word
LDMIA r0,{r4,r5,r6,r7}
MOV r1,#(16 * 1024)
......
; > TestSrc.ROMCard
TTL NCOS Support for ROM Cards
;
; Tests for presence of a 2,4 or 8MB OS image in 2nd ROM bank and jumps to it.
;
; This doesn't really belong in the POST sources, but lives here because it
; needs to happen soon after boot. This file is included inline by Begin before
; it starts calculating the ROM checksum
;
; Relies on width of the 2nd ROM bank already being set to 32bit.
; If 16bit extension ROM support is required then s.ARM600 must set ROMCR1 back
; to 16bit-wide.
;
; No registers are preserved and, unlike some other parts of the POST code, it
; assumes it is running on a fully-functional ARM & IOMD.
;
;------------------------------------------------------------------------
; History
;
; Date Name Comment
; ---- ---- -------
; 16-Aug-96 JRH First release
; 05-Sep-96 BAR Add code to switch out the progress colour screens.
; See begin (2.17 for details).
; Can't have CanLiveOnROMCard TRUE without ROMCardSupport
ASSERT ROMCardSupport
GBLL DebugROMCard
DebugROMCard SETL {FALSE}
ts_RC_MinOSsize * (2*1024*1024)
ts_RC_MaxOSsize * (8*1024*1024)
ts_RC_2ndbank * (16*1024*1024)
ts_RC_idoffset * -16 ; offset from end of image
ROMCardTest ROUT
; DEBUG: set up VIDC for VGA, assuming 32M clock
[ DebugROMCard
MOV r1, #ts_VIDCPhys
LDR r0, =&40ffffff ; White
STR r0, [r1]
]
[ CanLiveOnROMCard
TST pc, #ts_RC_2ndbank ; running out of 2nd ROM bank?
BNE %FT99 ; skip all this if so
]
[ DebugROMCard
LDR r0, =&4000ffff ; Yellow
STR r0, [r1]
]
MOV r12, #ts_RC_MinOSsize ; start with this size image
B %FT00
ts_RC_idword = "NCOS" ; id string
ts_RC_LDRPCInst & &E59FF
00
ADD r2, r12, #ts_RC_2ndbank ; end of image
LDR r1, ts_RC_idword ; id word to look for
LDR r0, [r2, #ts_RC_idoffset]
CMP r0, r1
BNE %FT90 ; try next size if no match
; Found the id string, now see if it checksums to 0.
; Following code ripped off from Mem3.
;
; r0 IS A POINTER TO THE LOCATIONS IN MEMORY.
; r1 HAS THE CALCULATED CHECKSUM.
; r2 HOLDS A COUNTER INDICATION HOW MANY WORDS ARE LEFT TO GET
; r3 is a temporary variable (no it isn't)
; r4 TO r11 ARE USED TO LOAD THE CONTENTS OF 8 LOCATIONS FROM THE ROM.
;
[ DebugROMCard
MOV r1,#ts_VIDCPhys
LDR r0, =&407f7fff ; Fetching Pink
STR r0, [r1]
]
MOV r1, #&00 ; initialise accumulator
MOV r0, #ts_RC_2ndbank ; initialise pointer
ADD r2, r0, r12 ; initialise endstop, >= 8 words
SUB r2, r2, #(8 * 4) ; below the real endpoint
RC_loop1
LDMIA r0!, {r4 - r11} ; get 8 words & post-inc
01
ADD r1, r1, r4
ADD r1, r1, r5
ADD r1, r1, r6
ADD r1, r1, r7
ADD r1, r1, r8
ADD r1, r1, r9
ADD r1, r1, r10
ADD r1, r1, r11
02
ASSERT ((%02 - %01) = 32) ; else r2 won't count down correctly
CMP r0, r2
BNE RC_loop1 ; loop until pointer reaches endstop
LDMIA r0, {r4 - r9} ; get last 6 words (miss last 2 in ROM)
03
ADD r1, r1, r4
ADD r1, r1, r5
ADD r1, r1, r6
ADD r1, r1, r7
ADD r1, r1, r8
ADDS r1, r1, r9 ; NOTE: Z set => checksum OK
04
ASSERT (((%04 - %03) + (2*4)) = 32)
BNE %FT90 ; Skip if checksum not zero
; We have a valid image. Now work out where to jump to in it.
; Can't just jump to the start because 1st instruction is an LDR PC.
; Code ripped off from Tim's Softloader (thanks Tim)
[ DontShowProgressColours
; Display "Jumping to 2nd ROM bank" colour
MOV_fiq r0,r12_fiq