;> RomCheck
; 
; RISC OS 2+ BOOT TEST SOFTWARE
; MEMORY TEST 3 VERSION A.
; BRIAN RICE 01-11-89
; 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.
;
;
; The test code for this test is a simple additive checksum routine.
; The software will read eight words from ROM then add the contents from ROM  
; to a register. When the test is complete the contents of the checksum
; register is checked by adding the final word in ROM - this should give 
; zero.
; The program will be run from ROM, at slowest speed.
;
; All except the last two words are checksummed : these hold the numbers
; that cause each individual ROM to CRC to zero, so they can't simultaneously
; be included in an all-zero additive checksum.

ts_CRCsize      *       (2 * 4)

;
;
;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
;r4 TO r11 ARE USED TO LOAD THE CONTENTS OF 8 LOCATIONS FROM THE ROM.
;
        ROUT

ts_ROM_checksum

;StrongARM_POST issue:
;ARM810 - this will probably go bang! because ARM810 aborts if the processor
;         vectors (00 - 1C) are read in 26-bit mode

         MOV    r1, #&00                    ; initialise accumulator    
	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

loop1    LDMIA  r0!, {r4 - r11}             ;LOAD r4 TO r11 WITH THE CONTENTS
                                            ;OF LOCATIONS POINTED TO BY r0
                                            ;WHICH IS INCREMEMTED AUTOMATICALLY
                                            ;TO POINT TO THE NEXT LOCATION
01
         ADD    r1, r1,          r4         ;ADD r4  TO CHECKSUM
         ADD    r1, r1,          r5         ;ADD r5  TO CHECKSUM
         ADD    r1, r1,          r6         ;ADD r6  TO CHECKSUM
         ADD    r1, r1,          r7         ;ADD r7  TO CHECKSUM
         ADD    r1, r1,          r8         ;ADD r8  TO CHECKSUM
         ADD    r1, r1,          r9         ;ADD r9  TO CHECKSUM
         ADD    r1, r1,          r10        ;ADD r10 TO CHECKSUM
         ADD    r1, r1,          r11        ;ADD r11 TO CHECKSUM
02
        ASSERT ((%02 - %01) = 32)       ; else r2 won't count down correctly
 
         CMPS   r0, r2
         BCC    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 r4  TO CHECKSUM
         ADD    r1, r1,          r5         ;ADD r5  TO CHECKSUM
         ADD    r1, r1,          r6         ;ADD r6  TO CHECKSUM
         ADD    r1, r1,          r7         ;ADD r7  TO CHECKSUM
         ADD    r1, r1,          r8         ;ADD r8  TO CHECKSUM
         ADD    r1, r1,          r9         ;ADD r9  TO CHECKSUM
04
        ASSERT  (((%04 - %03) + (2*4)) =  32) ; Change this if you like - 
                                            ; but be careful to count nearly
                                            ; to the top in eights, then add
                                            ; add in the last few words.

         MOVS   r0,r1                       ; should be zero if all OK

         MOV    pc,r14                      ;return with zero flag set on OK
                                            ;and the calculated sum in r0.


;
; ROM alias check.
; This test looks for an aliased copy of the vector table at varying
; distances from the start of ROM space.
; 16K is fairly arbitrary but corresponds approximately with the size of 
; the POST. If there's an alias below that, we've probably already crashed !
;
; This test is only called if the checksum fails, in order to indicate a
; possible high ROM address line failure.

ts_ROM_alias    ROUT

	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)

01      ADD     r2,r0,r1                ; get some words from possible alias
        LDMIA   r2,{r8,r9,r10,r11}
        CMPS    r4,r8
        CMPNE   r5,r9
        CMPNE   r6,r10
        CMPNE   r7,r11
        BEQ     %10                     ; aliased : found MS ROM address bit

        MOVS    r1, r1, LSL #1          ; test the next (more significant) bit
        CMPS    r1, r3                  ; reached the limit yet ?
        BLT     %01                     ; no - try again.

10      MOV     r0,r1                   ; reached the end, or an alias.
        MOV     pc,lr


  LTORG                     

  END