mac-rom/OS/StartMgr/STCritTests.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

1226 lines
37 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; File: STCritTests.a
;
; Contains: This file includes the critical test routines run at system start up. There are also
; some routines not run at startup but which are available to the Test Manager through
; the TJump Test Table.
;
; Copyright: © 1983-1991 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <2> 9/18/91 JSM Add a header.
; <2.6> 7/17/89 GMR Added extra pass through memory if parity exists for Mod3Test
; and RevMod3Test.
; <2.5> 7/15/89 GMR Added Gary D's optimized Mod3Test and RevMod3Test.
; <2.4> 7/8/89 CCH Modified to work with Romulator.
; <2.3> 6/26/89 GMR Changed to use (sp) instead of sp when referencing memory chunk
; table, to work with new size memory output.
; <2.2> 6/20/89 rle create stub call to size memory--need to return pointer to table
; in d6 for board burn in
; <2.1> 6/11/89 GMR Changed ref's to BaseOfRom to be BigLEA's.
; <2.0> 5/26/89 rle cleaned up file to remove obsolete code; address line test now
; runs the same for all machines (depends upon memory size
; location table)
; <1.9> 5/16/89 rle modified mod3 and revmod3 tests to run an additional pass for
; parity ram testing when parity ram is installed; modified
; address line test to function correctly for bank a only/bank b
; only/bank a and bank b systems; added dynamic bus sizing test
; <1.8> 4/11/89 rle import BaseOfRom for stub file builds
; <1.7> 3/28/89 rle now uses equates from "STEqu.a"
; <1.6> 3/6/89 GGD Modified to use pc-relative BaseOfROM instead of hard coded
; ROMStart equate to make code less hardware dependent.
; <1.5> 2/21/89 rwh fixed AddrLineTest to not use MacII code for FourSquare.
; <1.4> 2/16/89 rwh added support for Fitch Memory Controller rev 1. When FMC2
; arrives, may need to change these for a contiguous physical
; memory model.
; <1.3> 2/10/89 RLE update equates to support minimal f-19 build
; <1.2> 2/6/89 RLE replaced NuMac conditionals with more generic identifiers
; <1.1> 2/2/89 RLE STCritTests.a is now an independent file, responsible for
; importting and exportting the procedures it needs and others
; need; fixed a lot of conditional statements to make them more
; generic and less CPU-specific; adjusted address line test to run
; on MDU-based machines; still need to make it run from bank B
; <1.0> 1/11/89 RLE derived from version 1.4 of StartTest.a modified version history
; markers for all old versions to start with "[" instead of
; "<"--this allows changes in STCritTeststo be tracked separately;
; the SizeMemory routines were removed from this section; they are
; now under OS group control; we just jump to SizeMemory to find
; out the top of logical/physical memory
;
PRINT OFF
LOAD 'StandardEqu.d'
INCLUDE 'HardwareEqu.a'
INCLUDE 'STEqu.a' ; <v1.7>
IF hasIopScc THEN ; <v1.1>
INCLUDE 'IOPequ.a'
ENDIF
PRINT ON
IF CPU = 20 THEN
MACHINE MC68020
ENDIF
IF CPU = 30 THEN
MACHINE MC68030
ENDIF
STRING ASIS
CritProc PROC ; <v1.1>
EXPORT SizeMem ; <v2.2>
EXPORT Mod3Test
EXPORT RevMod3Test
EXPORT ExtRAMTest
EXPORT AddrLineTest
EXPORT DataBusTest
EXPORT StartUpROMTest
EXPORT RomTest
EXPORT NoTest
IF CPU > 10 THEN ; <v1.9>
EXPORT dynamic_bussize_test ; <v1.9>
ENDIF ; <v1.9>
IMPORT BaseOfRom ; <v1.8>
IMPORT SizeMemory ; <v2.2>
IMPORT RomLoc ; <v2.4>
IF hasMac2Via2 THEN ; <v1.1>
IMPORT BankASize ; <v1.1>
ENDIF ; <v1.1>
;--------------------------------------------------------------------------- <v2.2>
; This routine calls the OS SizeMemory routine, and returns the pointer <v2.2>
; to the memory location table in register d6. This is required for use <v2.2>
; with the test manager serial interface for board burn in. <v2.2>
;--------------------------------------------------------------------------- <v2.2>
;
SizeMem ; <v2.2>
move.l a6,a4 ;save return address (a4 not destroyed) <v2.2>
bsr6 SizeMemory ;make OS call <v2.2>
move.l (sp),d6 ;return start of memory location table <v2.2><v2.3>
jmp (a4) ;go back home <v2.2>
;
;---------------------------------------------------------------------------
; Data bus test walks 0 and 1 bits across the data buss to verify that
; memory can be accessed.
;
; On entry, a6 = return to caller.
; a0 = test address
;
; On exit, d6 = failed bit mask.
;
; Register usage:
;
; d0 = data bit register
; d1 = data bit register
; d2 = loop counter
;
; a0 = address pointer
;
; This test assumes interrupts are masked out with #$2500.
;---------------------------------------------------------------------------
;
DataBusTest
moveq #1,d0 ;first data pattern is 1 in 0's
moveq #-2,d1 ;next data pattern, $FFFFFFFE, 0 in 1's [C660>/[C798>
move.w #$00FF,d2 ;loop counter = 256
@10 movem.l d0-d1,(a0) ;write test patterns
eor.l d0,(a0) ;read and write low test location
or.l (a0),d6 ;if any bad bits, or to fail reg
eor.l d1,4(a0) ;read and write high test loc
or.l 4(a0),d6 ;if any bad bits, or to fail reg
rol.l #1,d0 ;rotate the bit
rol.l #1,d1 ;rotate the bit
dbra d2,@10 ;continue until bit shifted to carry
IF CPU = 00 THEN ; <v1.1>
move.l d6,d0 ;copy of longword bad bits
swap d0 ;bad bit mask to lower word
or.w d0,d6 ;
and.l #$0000FFFF,d6 ;only lower word [A322>
ENDIF
jmp (a6) ;return to caller, no errors
;
;---------------------------------------------------------------------------
; StartUpROMTest is run normally only at system startup. It uses the longword
; checksum residing in location 0. The Test Manager also supports a checksum test
; that uses the 2 or 4 sums residing in locations ROMStart+$0030 through $003F
; as separate sums for each ROM chip.
;
;---------------------------------------------------------------------------
;
StartUpROMTest
moveq #0,d0 ;clear checksum accumulator
moveq #0,d1 ;clear scratch
BigLea BaseOfROM,a0 ;point at ROM start, expected checksum <v1.6><2.1>
move.l (a0)+,d4 ;load up expected
move.l #myROMsize,d3 ;get appropriate size of ROM image less exp sum size
ROMLoop
move.w (a0)+,d0 ;fetch a ROM word
add.l d0,d1 ;add to checksum
subq.l #1,d3 ;count a loop
bne.s ROMLoop ;until done...
nop ;some nops for debug (leave these here for emulator use)
nop ;some nops for debug
eor.l d4,d1 ;result should be zero
CkSumBr beq.s @10
IF forRomulator THEN ; <2.4>
TestInRam A0 ; are we running in RAM? <2.4>
bne.s @10 ; if so, force chksum good <2.4>
ENDIF ; <2.4>
move.w #$FFFF,d6 ;set a failed code in result register [A310>
@10 jmp (a6) ;and exit
;---------------------------------------------------------------------------
;
; Mod3Test is a fast test of the entire memory array.
;
; Inputs: a0 = bottom memory area to test
; a1 = top of memory area to test + 1
; a6 = return to caller
;
; Outputs: d6.l is a failed bit mask
; a0,a1 still pointing to bottom and top of area to test
;
; Register usage:
;
; d0 = test data register
; d1 = test data register
; d2 = test data register
; d3 = test data register
; d4 = test data register
; d5 = test data register
; d6 = failed bit mask
;
; a0 = pointer to bottom test area
; a1 = pointer to top of test area
; a2 = copy of a0
; a3 = unsued
; a4 = unused
; a5 = unused
;
;
; This test writes a modulo 3 pattern to all of memory, then shifts the
; pattern by writing the appropriate starting pattern, reading the next
; in memory, exclusive oring this with the previous location, then writing
; it back to the same location. Any errors while reading (or writing) are
; propagated to the end of memory. At the end of the test the last 3 long
; word entries must be as expected or an error has occurred.
;
; In order to properly determine the failing bank with this test, it is best
; to call the test with a0/a1 set to test one bank at a time.
;
; There are three cases that can occur at the end of memory, depending on
; what size memory is being tested. Observe the last three long words:
;
; Case 0:
;
; (LAST-12) $BD6BD6BD (LAST-8) $D6BD6BD6 (LAST-4) $6BD6BD6B
;
; Case 1:
;
; (LAST-12) $D6BD6BD6 (LAST-8) $6BD6BD6B (LAST-4) $BD6BD6BD
;
; Case 2:
;
; (LAST-12) $6BD6BD6B (LAST-8) $BD6BD6BD (LAST-4) $D6BD6BD6
;
; The last three longs are compared against the appropriate table entries
; based on the case determined when memory is filled the first time.
; On exit, D6 reflects any bad bits found.
;
; This test should only be called with a0/a1 pointing at mod 4 bounds. The
; code assumes this and tests accordingly on 32 bit longword bounds, however
; calling this test with other bounds will result in a bus error since non-
; existent memory may be addressed. Also, upper - lower must be >= 24.
;
; This test assumes interrupts are masked out with #$2500.
;---------------------------------------------------------------------------
align 4
Mod3Test ; <2.5>
@FillRegs reg d0/d1/d2/d3/d4/d5
movem.l Mod3Pat,@FillRegs ;load up 2 copies of the test patterns
movea.l a0,a2 ; starting address
suba.w #120,a1 ; subtract slop from loop terminator
bra.s @Fill120Start
@Fill120Loop
movem.l @FillRegs,(a2)
movem.l @FillRegs,24(a2)
movem.l @FillRegs,48(a2)
movem.l @FillRegs,72(a2)
movem.l @FillRegs,96(a2)
adda.w #120,a2 ; point past block just written
@Fill120Start
cmpa.l a1,a2
ble.s @Fill120Loop ; fill until < 120 bytes remaining
suba.w #12-120,a1 ; subtract slop from loop terminator
moveq.l #12,d5 ; address increment value
bra.s @Fill12Start
@Fill12Loop
movem.l d0-d2,(a2)
adda.w d5,a2 ; point past bytes just written
@Fill12Start
cmpa.l a1,a2
ble.s @Fill12Loop ; fill until < 12 bytes remaining
adda.w d5,a1 ; restore end address
; Now pick up the last maximum 8 bytes not written
moveq #4,d4 ;case 0, offset = 4
cmpa.l a2,a1 ;maybe it came out even?
beq.s @FillDone ;done filling memory
move.l d0,(a2)+ ;write one more long
moveq #8,d4 ;case 1, offset = 8
cmpa.l a2,a1 ;compare against real mem top
beq.s @FillDone ;done filling memory
move.l d1,(a2)+ ;write one more long
moveq #0,d4 ;case 2, offset = 0
@FillDone
movea.l a0,a2 ;copy starting address
; Memory is filled with the mod 3 pattern. The pattern is sequenced through
; three iterations for the test by exclusive oring in the following manner.
move.l a1,d3 ;first get the top boundary
sub.l a0,d3 ; = number of bytes to test
subq.l #4,d3 ;less 4 bytes
moveq.l #$3F,d2 ; mask for index into loop
and.w d3,d2 ; compute the index
neg.w d2 ; index backwards
lsr.l #6,d3 ; 64 bytes per loop
eor.l d1,(a2) ;write starting pattern
addi.l #$FFFFFFFF,d5 ;help any floating bits float up
jmp @61(d2.w) ; jump to the correct starting position
@60 move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
move.l (a2)+,d2 ;read a pattern
eor.l d2,(a2) ;generate next pattern
@61 dbra d3,@60 ; until done
subi.l #$00010000,d3 ; adjust outer loop count
bpl.s @60
IF hasRBV THEN ; <v2.6>
cmp.w #ErrParRAM,d7 ;have we finished parity ram test? <v2.6>
beq @exit ;yep, we're outta here <v2.6>
ENDIF ; <v2.6>
; Now the final pass through the test area.
cmp.l d0,d1 ; is this the second pass
beq.s @62 ; if so, we're done
move.l d0,d1 ; use pattern from D0 on final pass
bra.s @FillDone ; make another pass
@62
; Now pick up the appropriate 3 longs nearest the end point. These should
; match patterns based on the case in d4, which was set up in the memory
; fill earlier. If any error occurred during eoring, it is propagated to the end.
movem.l -12(a1),d0-d2 ;pickup last 12 bytes
; and remember d4 is still set up..
movem.l Mod3Pat(d4.w),d3-d5 ;get original test patterns
eor.l d3,d0
eor.l d4,d1
eor.l d5,d2
or.l d2,d0
or.l d1,d0 ;compile final "bad bit" mask
or.l d0,d6 ;record for caller
IF CPU=00 THEN ; <1.1>
swap d0 ;bad bit mask to lower word
or.w d0,d6 ;
and.l #$0000FFFF,d6 ;only pass back lower word mask
ENDIF
IF hasRBV THEN ; <v2.6>
btst #parity,d7 ;determine need for parity ram test <v2.6>
beq.s @exit ;no parity ram, we're done <v2.6>
move.w #ErrParRAM,d7 ;set parity ram error code <v2.6>
movem.l Mod3Pat+4,@FillRegs ;load up 2 copies of the test patterns <v2.6>
bra @FillDone ;do one more pass if parity ram installed <v2.6>
ENDIF ; <v2.6>
@exit RTS6 ;and return
; Table of test and compare patterns
Mod3Pat
dc.l $6DB6DB6D ;case 2, offset = 0
dc.l $B6DB6DB6 ;case 0, offset = 4
dc.l $DB6DB6DB ;case 1, offset = 8
dc.l $6DB6DB6D
dc.l $B6DB6DB6
dc.l $DB6DB6DB
dc.l $B6DB6DB6
;---------------------------------------------------------------------------
;
; RevMod3Test is a fast test of the entire memory array, very similar to the
; Mod3Test above. It tests memory with the test addresses generated in the
; reverse direction.
;
; changed reg a3 to a2 in following code to make it like mod3test
; and to free-up a3 for other stuff
;
; Inputs: a0 = bottom memory area to test
; a1 = top of memory area to test + 1
; a6 = return to caller
;
; Outputs: d6.l is a failed bit mask
; a0,a1 still pointing to bottom and top of area to test
;
; Register usage:
;
; d0 = test data register
; d1 = test data register
; d2 = test data register
; d3 = test data register
; d4 = test data register
; d5 = test data register
; d6 = failed bit mask
;
; a0 = pointer to bottom test area
; a1 = pointer to top of test area
; a2 = copy of a1
; a3 = unused
; a4 = unused
; a5 = unused
;
; This test writes a modulo 3 pattern to all of memory, then shifts the
; pattern by writing the appropriate starting pattern, reading the next
; in memory, exclusive oring this with the previous location, then writing
; it back to the same location. Any errors while reading (or writing) are
; propagated to the beginning of memory. At the end of the test the first 3
; long word entries must be as expected or an error has occurred.
;
; In order to properly determine the failing bank with this test, it is best
; to call the test with a0/a1 set to test one bank at a time.
;
; There are three cases that can occur at the end of memory, depending on
; what size memory is being tested. Observe the last three long words:
;
; Case 0: must write 3 more longs to fill memory, table offset = 8 for
; correct final compare patterns.
;
; (FIRST+0) $6BD6BD6B (FIRST+4) $BD6BD6BD (FIRST+8) $D6BD6BD6
;
; Case 1: must write 1 more long to fill memory, table offset = 4 for
; correct final compare patterns.
;
; (FIRST+0) $D6BD6BD6 (FIRST+4) $6BD6BD6B (FIRST+8) $BD6BD6BD
;
; Case 2: must write 2 more longs to fill memory, table offset = 0 for
; correct final compare patterns.
;
; (FIRST+0) $BD6BD6BD (FIRST+4) $D6BD6BD6 (FIRST+8) $6BD6BD6B
;
; The first three longs are compared against the appropriate table entries
; based on the case determined when memory is filled the first time.
; On exit, D6 reflects any bad bits found.
;
; This test should only be called with a0/a1 pointing at mod 4 bounds. The
; code assumes this and tests accordingly on 32 bit longword bounds, however
; calling this test with other bounds will result in a bus error since non-
; existent memory may be addressed. Also, upper - lower must be >= 24.
;
; This test assumes interrupts are masked out with #$2500.
;
;---------------------------------------------------------------------------
align 4
RevMod3Test ; <2.5>
@FillRegs reg d0/d1/d2/d3/d4/d5
movem.l RevMod3Pat,@FillRegs ;load up 2 copies of the test patterns
movea.l a1,a2 ; starting address
adda.w #120,a0 ; add slop to loop terminator
bra.s @Fill120Start
@Fill120Loop
movem.l @FillRegs,-(a2)
movem.l @FillRegs,-(a2)
movem.l @FillRegs,-(a2)
movem.l @FillRegs,-(a2)
movem.l @FillRegs,-(a2)
@Fill120Start
cmpa.l a2,a0
ble.s @Fill120Loop ; fill until < 120 bytes remaining
adda.w #12-120,a0 ; add slop to loop terminator
bra.s @Fill12Start
@Fill12Loop
movem.l d0-d2,-(a2)
@Fill12Start
cmpa.l a2,a0
ble.s @Fill12Loop ; fill until < 12 bytes remaining
suba.w #12,a0 ; restore bottom address
; Now pick up the last maximum 8 bytes not written
moveq #8,d4 ;case 0, offset = 8
cmpa.l a2,a0 ;compare against real mem bottom
beq.s @FillDone ;done filling memory
move.l d2,-(a2) ;write one more long
moveq #4,d4 ;case 1, offset = 4
cmpa.l a2,a0 ;compare against real mem bottom
beq.s @FillDone ;done filling memory
move.l d1,-(a2) ;write one more long
moveq #0,d4 ;case 2, offset = 0
@FillDone
movea.l a1,a2 ;copy ending address
subq.l #4,a2 ;adjust to last longint
; Memory is filled with the mod 3 pattern. The pattern is sequenced through
; three iterations for the test by exclusive oring in the following manner.
move.l a2,d3 ;first get the top boundary
sub.l a0,d3 ; = number of bytes to test
moveq.l #$3F,d0 ; mask for index into loop
and.w d3,d0 ; compute the index
neg.w d0 ; index backwards
lsr.l #6,d3 ; 64 bytes per loop
eor.l d1,(a2) ;write starting pattern
addi.l #$FFFFFFFF,d5 ;help any floating bits float up
jmp @61(d0.w) ; jump to the correct starting position
@60 move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
move.l (a2),d0 ;read a pattern
eor.l d0,-(a2) ;generate next pattern
@61 dbra d3,@60 ; until done
subi.l #$00010000,d3 ; adjust outer loop count
bpl.s @60
IF hasRBV THEN ; <v2.6>
cmp.w #ErrParRAM,d7 ;have we finished parity ram test? <v2.6>
beq @exit ;yep, we're outta here <v2.6>
ENDIF ; <v2.6>
; Now the final pass through the test area.
cmp.l d2,d1 ; is this the second pass
beq.s @62 ; if so, we're done
move.l d2,d1 ; use pattern from D2 on final pass
bra.s @FillDone ; make another pass
@62
; Now pick up the appropriate 3 longs nearest the end point. These should
; match patterns based on the case in d4. If any error occurred during
; eoring, it is propagated through to the end.
movem.l (a0),d0-d2 ;pickup first 12 bytes
movem.l RevMod3Pat(d4.w),d3-d5 ;get original test patterns
eor.l d3,d0
eor.l d4,d1
eor.l d5,d2
or.l d2,d0
or.l d1,d0 ;compile final "bad bit" mask
or.l d0,d6 ;record for caller
IF CPU=00 THEN ; <1.1>
swap d0 ;bad bit mask to lower word
or.w d0,d6 ;
and.l #$0000FFFF,d6 ;only pass back lower word mask
ENDIF
IF hasRBV THEN ; <v2.6>
btst #parity,d7 ;determine need for parity ram test <v2.6>
beq.s @exit ;no parity ram, we're done <v2.6>
move.w #ErrParRAM,d7 ;set parity ram error code <v2.6>
movem.l RevMod3Pat+4,@FillRegs ;load up 2 copies of the test patterns <v2.6>
bra @FillDone ;do one more pass if parity ram installed <v2.6>
ENDIF ; <v2.6>
@exit RTS6 ;and return
RevMod3Pat
dc.l $6DB6DB6D ;case 2, offset = 0
dc.l $B6DB6DB6 ;case 0, offset = 4
dc.l $DB6DB6DB ;case 1, offset = 8
dc.l $6DB6DB6D
dc.l $B6DB6DB6
dc.l $DB6DB6DB
dc.l $B6DB6DB6
;---------------------------------------------------------------------------
; RomTest does a ROM checksum on the individual ROMs and returns an error
; code in d6 indicating any failed ROMs. The checksums are located in the
; ROMs at dedicated addresses, forever defined to be as follows:
;
; ROM 0 at ROMStart + $0030 - $0033
; ROM 1 at ROMStart + $0034 - $0037
; ROM 2 at ROMStart + $0038 - $003B
; ROM 3 at ROMStart + $003C - $003F
;
; On entry: d6 = 0
; On exit: d6 = $0000000X, where X = abcd, and a means ROM 3,
; b means ROM 2, c means ROM 1, and d means ROM 0
;
; This test assumes interrupts are masked out with #$2500.
;
;---------------------------------------------------------------------------
;
RomTest
lea myROMSums,a1 ;point to end of first area
BigLea BaseOfROM,a0 ;point to start of ROM code <v1.6><2.1>
move.l (a0)+,d0 ;discard first long word of ROM
move.l a1,a2 ;keep a copy
clr.l d0 ;clear summing registers
clr.l d1
clr.l d2
clr.l d3
clr.l d4
clr.l d5
IF CPU = 00 THEN ; <v1.2>
@10 move.w (a0)+,d5 ;read out 2 bytes
move.b d5,d4 ;get byte 1
add.l d4,d1 ;byte 1 sum
lsr.l #8,d5 ;align next byte
move.b d5,d4 ;get byte 0
add.l d4,d0 ;byte 0 sum
ELSE ; <v1.2>
@10 move.l (a0)+,d5 ;read out 4 bytes
move.b d5,d4 ;get byte 3
add.l d4,d3 ;byte 3 sum
lsr.l #8,d5 ;align next byte
move.b d5,d4 ;get byte 2
add.l d4,d2 ;byte 2 sum
lsr.l #8,d5 ;align next byte
move.b d5,d4 ;get byte 1
add.l d4,d1 ;byte 1 sum
lsr.l #8,d5 ;align next byte
move.b d5,d4 ;get byte 0
add.l d4,d0 ;byte 0 sum
ENDIF
cmpa.l a0,a1 ;done yet?
bgt.s @10
; Now we jump past the 16 bytes of sums that live in low ROM space.
adda.l #16,a0 ;pointing at code again
lea myROMEnd,a1 ;and end of ROM image + 1
IF CPU = 00 THEN ; <v1.2>
@15 move.w (a0)+,d5 ;read out 2 bytes
move.b d5,d4 ;get byte 1
add.l d4,d1 ;byte 1 sum
lsr.l #8,d5 ;align next byte
move.b d5,d4 ;get byte 0
add.l d4,d0 ;byte 0 sum
ELSE ; <v1.2>
@15 move.l (a0)+,d5 ;read out 4 bytes
move.b d5,d4 ;get byte 3
add.l d4,d3 ;byte 3 sum
lsr.l #8,d5 ;align next byte
move.b d5,d4 ;get byte 2
add.l d4,d2 ;byte 2 sum
lsr.l #8,d5 ;align next byte
move.b d5,d4 ;get byte 1
add.l d4,d1 ;byte 1 sum
lsr.l #8,d5 ;align next byte
move.b d5,d4 ;get byte 0
add.l d4,d0 ;byte 0 sum
ENDIF
cmpa.l a0,a1 ;done yet?
bgt.s @15
; a2 still points to the table of expected checksums in low ROM...
; Check all 4 even though on Aladdin bytes 2,3 will be 0.
move.l (a2)+,d4 ;byte 0 expected checksum
eor.l d4,d0 ;any error?
beq.s @20 ;no
bset #0,d6 ;yes, flag byte 0 checksum error
@20 move.l (a2)+,d4 ;byte 1 expected checksum
eor.l d4,d1 ;any error?
beq.s @30 ;no
bset #1,d6 ;yes, flag byte 1 checksum error
@30 move.l (a2)+,d4 ;byte 2 expected checksum
eor.l d4,d2 ;any error?
beq.s @40 ;no
bset #2,d6 ;yes, flag byte 2 checksum error
@40 move.l (a2)+,d4 ;byte 3 expected checksum
eor.l d4,d3 ;any error?
beq.s @50 ;no
bset #3,d6 ;yes, flag byte 3 checksum error
@50 jmp (a6) ;exit test
;---------------------------------------------------------------------------
; ExtRAMTest is a March pattern for testing RAM. The algorithm is:
;
; a) write zeros to all RAM incrementing addresses
; b) read/verify/invert incrementing
; c) read/verify/invert decrementing
; d) read/verify/invert incrementing
; e) read/verify decrementing
;
; On entry:
;
; a0 = points to start of test area
; a1 = points to end of test area
;
; Register usage:
;
; a0 = points to start of test area
; a1 = points to end of test area
; a2 = working address pointer
;
; d0 = data pattern
; d1 = inverted data pattern
; d2 = loop counter
; d3 = saved loop counter
;
; This test assumes interrupts are masked out, except for power off in NuMac.
;
;---------------------------------------------------------------------------
ExtRAMTest
moveq #0,d0 ;starting data = 0
moveq #-1,d1 ;inverted data = $FFFFFFFF
move.l a0,a2 ;copy start area
move.l a1,d2 ;first get the top boundary
sub.l a0,d2 ; = number of bytes to test
lsr.l #2,d2 ;divide by 4
move.l d2,d3 ;and keep a copy
@10 move.l d0,(a2)+ ;write a pattern
subq.l #1,d2 ;count it
bne.s @10 ;until done
; RAM is at all 0's now
; Now read/verify/invert incrementing
move.l d3,d2 ;get count
move.l a0,a2 ;and pointer
@20 tst.l (a2) ;read/verify
bne.s @1000 ;error
eor.l d1,(a2)+ ;read/invert to 1's
subq.l #1,d2 ;count it
bne.s @20 ;until done
; RAM is at all 1's now
; Read/verify/invert decrementing, a2 points to 1 long past the top area
move.l d3,d2 ;get count
@30 eor.l d1,-(a2) ;read/invert to 0's
bne.s @1000 ;error
subq.l #1,d2 ;count it
bne.s @30 ;until done
; RAM is at all 0's now
; Read/verify/invert incrementing, a2 points to start of test area
move.l d3,d2 ;get count
@40 tst.l (a2) ;read/verify
bne.s @1000 ;error
eor.l d1,(a2)+ ;read/invert to 1's
subq.l #1,d2 ;count it
bne.s @40 ;until done
; RAM is at all 1's now
; Read/verify/invert decrementing, a2 points to 1 long past the top area
move.l d3,d2 ;get count
@50 eor.l d1,-(a2) ;read/invert to 0's
bne.s @1000 ;error
subq.l #1,d2 ;count it
bne.s @50 ;until done
; RAM is at all 0's now
; Read/verify incrementing, a2 points to start of test area
move.l d3,d2 ;get count [C354>
@60 tst.l (a2)+ ;read/verify
bne.s @1000 ;error
subq.l #1,d2 ;count it
bne.s @60 ;until done
jmp (a6) ;return no error
@1000 or.l (a2),d6 ;or in bad bits
IF CPU = 00 THEN ; <v1.1>
move.l d6,d0 ;copy 32 bit mask
swap d0 ;bad bit mask to lower word
or.w d0,d6 ;
and.l #$0000FFFF,d6 ;only pass back lower word mask
ENDIF
jmp (a6)
;---------------------------------------------------------------------------
; AddrLineTest
;
; This test writes a pattern in each memory address according to its address bit,
; then reads each back and verifies the pattern. This is then repeated in reverse.
;
; The addresses tested are $0,$4,$8,$10,$20,$40...$n00000.. to bank A bound if
; more than 1 bank exists, or to bank A bound div 2 if only one bank.
;
; On entry: d6 = 0
; a6 = return address
; (sp) = pointer to memory location table
;
; On exit: d6 = bit map of any bad address line, 0 if no errors
; a6 = return address
; (sp) = pointer to memory location table
;
;---------------------------------------------------------------------------
AddrLineTest
;;compute top of memory <v1.9>
move.l (sp),a1 ;move memory table pointer into a1 <v1.9><v2.3>
addq.l #8,a1 ;point to end of table for one bank systems <v1.9>
move.l #$01ffffff,d4 ;set up mask <v1.9>
@402 cmpi.l #-1,(a1) ;search for end of table <v1.9>
beq.s @404 ;found it! <v1.9>
move.l (sp),a1 ;move memory table pointer into a1 <v1.9><v2.3>
move.l (a1)+,a2 ;move beginning of bank A into a2 <v1.9>
add.l (a1)+,a2 ;compute top of bank A <v1.9>
addq.l #8,a1 ;point to next location field <v1.9>
bra.s @02 ;skip ahead <v1.9>
@404 subq.l #8,a1 ;go back to last location <v1.9>
move.l (a1)+,a0 ;move beginning memory location to a0 <v1.9>
add.l (a1)+,a0 ;add size to memory location to point to top <v1.9>
IF onMac | onMacPP | onHcMac THEN ;
move.l (sp),a1 ;move memory table pointer into a1 <v1.9><v2.3>
move.l (a1)+,a0 ;move beginning of bank A into a0 <v1.9>
add.l (a1)+,a0 ;compute top of bank A <v1.9>
move.l a0,d0 ;get top of memory
lea K512,a2 ;prep with top of 512K constant
cmp.l #Meg1,d0 ;see if RAM size > 1Meg
ble.s @000 ;yes it is
lea Meg2,a2 ;prep with top of 2Meg constant
@000
ELSE ; <v1.9>
move.l (sp),a1 ;move memory table pointer into a1 <v1.9><v2.3>
move.l (a1)+,a2 ;move beginning of bank A into a2 <v1.1>
add.l (a1)+,a2 ;compute top of bank A <v1.1>
ENDIF ; <v1.1>
; Now a2 has the top of bank A + 1, lets first see if thats the top of [contiguous] RAM
cmp.l a2,a0 ;a2 = top of Bank A, a0 = top of RAM
bgt.s @05 ;there is more than 1 bank
@02 move.l a2,d0 ;there is only 1 bank, so shift test address
lsr.l #1,d0
and.l d4,d0 ;mask out bank starting location <v1.9>
move.l d0,a2 ;and use it as the top address to test
@05
move.l (sp),a1 ;move memory table pointer into a1 <v1.9><v2.3>
move.l (a1),a1 ;load up beginning of bank A <v1.1>
clr.l (a1) ;clear first address in bank A <v1.1>
moveq #4,d5 ;first test data
@10 move.l d5,a3 ;generate test address
add.l a1,a3 ;add offset if necessary <v1.9>
move.l d5,(a3) ;write test data to test address
lsl.l #1,d5 ;calculate next test data *2
cmp.l a2,d5 ;see if done
ble.s @10
; Data has been written, read back in forward direction and verify
move.l (sp),a3 ;move memory table pointer into a1 <v1.9><v2.3>
move.l (a3),d0 ;should be 0
and.l d4,d0 ;mask out bank starting location <v1.9>
bne.s @1000 ;... else error
moveq #4,d5 ;first test data/address
@20 move.l d5,a3 ;generate test address
add.l a1,a3 ;add offset if necessary <v1.9>
move.l (a3),d0 ;read test data from test address
eor.l d5,d0 ;as expected?
bne.s @1000 ;no, error
lsl.l #1,d5 ;calculate next test data *2
cmp.l a2,d5 ;see if done
ble.s @20
; Now write data in backward direction, high to low addresses
move.l a2,d5 ;generate test data
lsl.l #1,d5 ;prime with 2*test data/address
@30 lsr.l #1,d5 ;calculate next test data div 2
cmp.l #4,d5 ;until data/address < 4
blt.s @35 ;until test data/address < 0
move.l d5,a3 ;generate test address
add.l a1,a3 ;add offset if necessary <v1.9>
move.l d5,(a3) ;write test data to test address
bra.s @30 ;again
; Data has been written, read back forward and verify
@35 sub.l a3,a3 ;start at RAM bottom again
add.l a1,a3 ;add offset if necessary <v1.9>
move.l (a3),d0 ;should be 0
and.l d4,d0 ;mask out bank starting location <v1.9>
bne.s @1000 ;... else error
moveq #4,d5 ;first test data/address
@40 move.l d5,a3 ;generate test address
add.l a1,a3 ;add offset if necessary <v1.9>
move.l (a3),d0 ;read test data from test address
eor.l d5,d0 ;as expected?
bne.s @1000 ;no, error
lsl.l #1,d5 ;calculate next test data *2
cmp.l a2,d5 ;see if done
ble.s @40
clr.l d0 ;done, clear error accumulator
@1000 move.l d0,d6 ;set any failed bits for caller
jmp (a6) ;return to caller
;
;---------------------------------------------------------------------------
; No Test implemented
;
;---------------------------------------------------------------------------
NoTest
moveq #0,d6
jmp (a6)
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;dynamic bus sizing tests
;table for dynamic bus-sizing test must be kept in this order
dbs_table dc.l $00112233 ;pattern for 1st two lw's lw bound
dc.l $88888888
dc.l $88001122 ;lw+1(offset)
dc.l $33888888
dc.l $88880011 ;lw+2(offset)
dc.l $22338888
dc.l $88888800 ;lw+3(offset)
dc.l $11223388
dc.l $88888888 ;lw+4(offset)
dc.l $00112233
;expected patterns for word accesses
dc.l $00118888 ;w+0(offset)
dc.l $88888888
dc.l $88001188 ;w+1(offset)
dc.l $88888888
dc.l $88880011 ;w+2(offset)
dc.l $88888888
dc.l $88888800 ;w+3(offset)
dc.l $11888888
dc.l $88888888 ;w+4(offset)
dc.l $00118888
;expected patterns for byte accesses
dc.l $00888888 ;b+0(offset)
dc.l $88888888
dc.l $88008888 ;b+1(offset)
dc.l $88888888
dc.l $88880088 ;b+2(offset)
dc.l $88888888
dc.l $88888800 ;b+3(offset)
dc.l $88888888
dc.l $88888888 ;b+4(offset)
dc.l $00888888
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; dynamic_bussize_test: this test will verify that the dynamic bus sizing of the
; 68020/68030 and dram memory subsystem are working properly.
; this is accomplished by writing longword, word, and byte data
; to locations + offset within a constant field of two longwords
; and then verifying that the correct bytes were written that
; constant field of two longwords
;
;
; entry: a0.l = ptr to valid ram on longword boundary
; a6.l = return address for bsr6
;
; exit: if pass
; d6.l = 0
;
; else
; d6.l = bitmask of failures in the following format
;
; bit 0 set means lw + 0 (offset) test failed
; bit 1 set means lw + 1 (offset) test failed
; .
; .
; .
; bit 14 set means byte + 4 (offset) test failed
;
; see dbs_table for expected patterns
;
;
; altered: d0.l - d6.l, a1.l - a2.l
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;do longwords 1st
dynamic_bussize_test
move.l #%0111111111111111,d6 ;init failure mask
lea.l dbs_table,a1 ;ptr to table of expected results
lea.l dbs_table+4,a2 ;ptr to background pattern
move.l #$00112233,d0 ;initialize write pattern
clr.l d1 ;init bit position holder and offset values
dbs_lwb1 move.l (a2),(a0) ;write background pattern 2 longwords
move.l (a2),4(a0)
move.l d0,(a0,d1.w) ;write pattern to ram lw + offset
movem.l (a0),d2-d3 ;read back lw's on lw bounds
movem.l (a1)+,d4-d5 ;get expected pattern from table
cmp.l d4,d2 ;does 1st lw match expected
bne.s dbs_lwb2 ;no, skip mask update
cmp.l d5,d3 ;how about 2nd lw
bne.s dbs_lwb2 ;no, skip mask update
swap d1 ;get bit position info to update fail bitmask
bclr.l d1,d6 ;clear appropriate bit to indicate pass this test
swap d1 ;restore offset to lower word
dbs_lwb2 addq.l #1,d1 ;bump address offset
swap d1 ;get bit position info to update fail bitmask
addq.w #1,d1 ;bump bit position to for next offset test
swap d1 ;restore offset to lower word
cmpi.b #4,d1 ;all offsets tried
bls.s dbs_lwb1 ;no, do another
;;;;;;;;;;;;;;
;now do words
dbs_word move.w #$0011,d0 ;initialize write pattern
clr.w d1 ;init bit position holder and offset values
@dbs_lwb1 move.l (a2),(a0) ;write background pattern 2 longwords
move.l (a2),4(a0)
move.w d0,(a0,d1.w) ;write pattern to ram lw + offset
movem.l (a0),d2-d3 ;read back lw's on lw bounds
movem.l (a1)+,d4-d5 ;get expected pattern from table
cmp.l d4,d2 ;does 1st lw match expected
bne.s @dbs_lwb2 ;no, skip mask update
cmp.l d5,d3 ;how about 2nd lw
bne.s @dbs_lwb2 ;no, skip mask update
swap d1 ;get bit position info to update fail bitmask
bclr.l d1,d6 ;clear appropriate bit to indicate pass this test
swap d1 ;restore offset to lower word
@dbs_lwb2 addq.l #1,d1 ;bump address offset
swap d1 ;get bit position info to update fail bitmask
addq.w #1,d1 ;bump bit position to for next offset test
swap d1 ;restore offset to lower word
cmpi.b #4,d1 ;all offsets tried
bls.s @dbs_lwb1 ;no, do another
;;;;;;;;;;;;;;;;;;;;;;;;
;and finally bytes
dbs_byte clr.l d0 ;initialize write pattern
clr.w d1 ;init bit position holder and offset values
@dbs_lwb1 move.l (a2),(a0) ;write background pattern 2 longwords
move.l (a2),4(a0)
move.b d0,(a0,d1.w) ;write pattern to ram lw + offset
movem.l (a0),d2-d3 ;read back lw's on lw bounds
movem.l (a1)+,d4-d5 ;get expected pattern from table
cmp.l d4,d2 ;does 1st lw match expected
bne.s @dbs_lwb2 ;no, skip mask update
cmp.l d5,d3 ;how about 2nd lw
bne.s @dbs_lwb2 ;no, skip mask update
swap d1 ;get bit position info to update fail bitmask
bclr.l d1,d6 ;clear appropriate bit to indicate pass this test
swap d1 ;restore offset to lower word
@dbs_lwb2 addq.l #1,d1 ;bump address offset
swap d1 ;get bit position info to update fail bitmask
addq.w #1,d1 ;bump bit position to for next offset test
swap d1 ;restore offset to lower word
cmpi.b #4,d1 ;all offsets tried
bls.s @dbs_lwb1 ;no, do another
jmp (a6) ;return to caller
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; <v1.9>
END ; <v1.1>