; > 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).
; 05-Aug-98     NCE     Changes for Customer F maintainance OS.
;                       Front panel button skips lookng for ROM banks.
;                       Support for 3rd Rom bank.


;	Can't have CanLiveOnROMCard TRUE without ROMCardSupport
	ASSERT	ROMCardSupport

	GBLL	DebugROMCard
DebugROMCard	SETL	{FALSE}

ts_RC_1meg      *       (1*1024*1024)
ts_RC_MinOSsize	*	(2*1024*1024)
ts_RC_MaxOSsize	*	(8*1024*1024)
ts_RC_2ndbank	*	(16*1024*1024)
ts_RC_3rdbank   *       (24*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
  	CMP    pc, #ts_RC_2ndbank  		;skip this stuff if already 
  	BGT    %FT99               		;running in 2nd bank of higher
  ]
  
  [  IOMD_C_FrontPanelButton <> 0 
   [ :LNOT: FrontPanelButtClearsCMOS
     MOV     r0, #IOMD_Base          ; if front panel button pressed then skip this       
     LDRB    r0, [r0, #IOMD_CLINES]  ; stuff and run the maintainance OS 
     TST     r0, #IOMD_C_FrontPanelButton
     BEQ     %FT99
   ]   
  ]

  [ DebugROMCard
        LDR     r0, =&4000ffff			; Yellow
        STR     r0, [r1]
  ]


        MOV     r3,#ts_RC_3rdbank            ;lr contains the address of the ROM were looking for
                                             
40
        MOV     r12, r3                         ; try to pull ROM size out of the image
        LDR     r12, [r12, #ROMSizeOffset]      ; if this fails then we will start at r3 and work up
        CMP	r12, #ts_RC_MaxOSsize
        BHI	%FT90

ts_RC_idword	=	"NCOS"			; id string
ts_RC_LDRPCInst	&	&E59FF

00
	ADD	r2, r12, r3		; 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, r3          		; 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              	; restore the faultcode bits
        ANDS    r0,r0,#(R_EXTERN :OR: R_TESTED)	; If test adapter present,
			                   	; NE : Adaptor fitted, show progress.
 	           				; EQ : No Adaptor fitted, don't show progress
	BEQ	%FT10				; EQ : Don't show colours
	]
        MOV	r1, #ts_VIDCPhys
        LDR	r0, =C_2NDBANK
        STR	r0, [r1]
10

  [ DebugROMCard
; Delay
	MOV	r0, #0
	MOV	r1, #(2*1024*1024)
15
	LDMIA	r0!, {r2}
	CMP	r0, r1
	BNE	%BT15
  ]
	MOV	r0, r3          		; start of 2nd ROM image
	LDR	r6, [r0]			; load 1st instruction of ROM image
	AND	r2, r6, #&FF000000
	TEQ	r2, #&EA000000			; is it a branch
	BNE	%FT20				; [no, so try something else]

	MOV	r6, r6, LSL #(32-21)		; extract offset within ROM
	ADD	r0, r0, r6, LSR #(32-21-2)	; convert to byte offset
	ADD     pc, r0, #8			; allow for pre-fetch

; check for LDR PC, [PC, +/-#x]
20	MOV     r4, r6, LSR #12
	LDR     r5, ts_RC_LDRPCInst
	ORR	r4, r4, #1 << (23-12)
	TEQ	r4, r5
30	; endlessloop
	BNE	%BT30				; not either, so stuck

	EOR	r6, r6, r4, LSL #12		; extract offset, and up/down bit
	TST	r6, #1 << 23			; NE => bit was 0, so -ve
	RSBNE	r6, r6, #1 << 23		; get rid of bit 23 and negate
	ADD	r6, r6, #8			; offset in ROM we're reading
	LDR	r6, [r0, r6]			; address to jump to
	ADD	pc, r0, r6			; jump to it

; Try the other ROM bank
90
        CMP     r3, #ts_RC_2ndbank              
        BEQ     %FT91
        MOV     r3,#ts_RC_2ndbank
        B       %BT40

91
  [ DebugROMCard
        MOV	r1, #ts_VIDCPhys
        LDR	r0, =&407fff7f			; Pale Green
        STR	r0, [r1]
; Delay
	MOV	r0, #0
	MOV	r1, #(2*1024*1024)
95
	LDMIA	r0!, {r2}
	CMP	r0, r1
	BNE	%BT95

	B	%FT99				; No image found

	LTORG
  ]

; Fall through to POST code
99
	END