mac-rom/OS/StartMgr/USTCritTests.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

1153 lines
38 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: USTCritTests.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-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM5> 01/07/93 HY In AddrLineTest save return address in A4 instead
; of A3 before calling SizeMemory.
; <SM4> 8/20/92 CCH Removed unneeded ÒforRiscÓ conditional.
; <SM3> 7/13/92 CCH Don't check checksum when running on Cub Card.
; <SM2> 5/2/92 kc Roll in Horror. Comments follow:
; <H2> 01/27/92 jmp (BG,Z6) Added padding in Mod3Test and RevMod3Test because of our
; STUPIP assembler optimizes things even when we dont want it to.
; Also, conditionalized the PROC parts of this file for use in
; lining up the UST part of HORROR with that of TERROR/Zydeco.
; <T5> 4/2/91 CCH Rolled in changes from Scott Smyers': Made the startupROM test
; always pass when built forRomulator but executed in ROM, not
; RAM. (it used to fail when run in ROM, but force a pass when run
; in RAM).
; <T4> 12/14/90 HJR Cleaned up the ROM checksum routines.
; <T3> 9/9/90 CCH Fixed StartupROMTest to deal with one-meg ROMs as well.
; <T2> 9/5/90 CCH Modifying ROM checksum test to deal with one-meg ROMs.
; <14> 1/23/92 RB Forced a good ROM checksum when compiled forRomulator.
; <13> 9/18/91 JSM Cleanup header.
; <12> 10/30/90 SS Tweeked fix <11> so that it uses the ROMHeader structure instead
; of equates in STEqu.a.
; <11> 10/22/90 SS Fixed the ROM checksum routines so that they do not rely on a
; build specific equate to get the ROM size. This is so that the
; same code will work when we go to a 1 Meg ROM without having to
; add another conditional flag to activate the 1 Meg ROM size
; equate. Also cleaned up the code a little in these routines.
; <10> 9/20/90 BG Removed <8>. 040s are now behaving more reliably.
; <9> 8/2/90 CCH Added NOPs between consecutive MOVEMs for flaky 040s.
; <8> 4/26/90 SS In AddrLineTest, return an error from SizeMemory if it fails.
; <7> 4/26/90 SS Rewrote the address line test to test all of memory, not just
; bank A. It will work even if banks are non-contiguous. I also
; added a call to SizeMemory to this test so that you don't have
; to run the SizeMem test immediately before running this one.
; <6> 4/24/90 SS In the byte lane ROM checksum test, I changed to use offsets for
; the address of the checksum in ROM and the end of ROM, instead
; of whole hardcoded addresses.
; <5> 4/20/90 SS Changed the way I increment a register in the extended RAM test
; to make it a little faster.
; <4> 3/30/90 SS Fixed a register usage problem which was destroying results in
; one of the RAM tests if an error was found on the last pattern
; test. Note that this test is only run in RBI and test manager -
; not on power up.
; <3> 2/16/90 SS Added flags to statements which were changed to support Ericson.
; <2> 2/12/90 MA Added moving inversions RAM test. It is not executed at
; startup, but is executed by the Test Manager the same as other
; mem. tests.
; <1.3> 8/22/89 GMR Included the rest of Fremonts critical tests in this file.
; <1.2> 7/25/89 CCH If forRomulator flag is set, checksum is forced good when
; running in RAM.
; <1.1> 7/15/89 GMR Fixed CPU=00 conditional for the RAM tests.
; <1.0> 6/13/89 GMR Added for first time to EASE.
;
STRING ASIS
CritProc PROC
IMPORT BaseOfRom
IMPORT SizeMemory ;<7>
EXPORT Mod3Test
EXPORT RevMod3Test
EXPORT RomTest
EXPORT StartUpROMTest
EXPORT ExtRAMTest
EXPORT AddrLineTest
EXPORT DataBusTest
EXPORT dynamic_bussize_test
EXPORT MovInvTest ;<3>
EXPORT NoTest
;---------------------------------------------------------------------------
;
; 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
@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
cmp.w #ErrParRAM,d7 ;have we finished parity ram test?
beq @exit ;yep, we're outta here
; 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
btst #parity,d7 ;determine need for parity ram test
beq.s @exit ;no parity ram, we're done
move.w #ErrParRAM,d7 ;set parity ram error code
movem.l Mod3Pat+4,@FillRegs ;load up 2 copies of the test patterns
bra @FillDone ;do one more pass if parity ram installed
@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
;---------------------------------------------------------------------------
;
; 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
@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
cmp.w #ErrParRAM,d7 ;have we finished parity ram test?
beq @exit ;yep, we're outta here
; 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
btst #parity,d7 ;determine need for parity ram test
beq.s @exit ;no parity ram, we're done
move.w #ErrParRAM,d7 ;set parity ram error code
movem.l RevMod3Pat+4,@FillRegs ;load up 2 copies of the test patterns
bra @FillDone ;do one more pass if parity ram installed
@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
;---------------------------------------------------------------------------
; 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,
; d means ROM 0
;
; This test assumes interrupts are masked out with #$2500.
;
;---------------------------------------------------------------------------
RomTest
WITH ROMHeader ; <12>
BigLea BaseOfROM,a0 ;point to start of ROM code <11>
lea CheckSum0(a0),a1 ;point to end of first area <12><11>
move.l ROMSize(a0),d0 ;and size of ROM <12><11>
lea.l (a0,d0.l),a2 ;calculate the end of ROM <11>
ENDWITH
clr.l d0 ;clear summing registers
clr.l d1
clr.l d2
clr.l d3
clr.l d4 ;holds a byte from ROM to sum
addq.l #4,a0 ;skip past first long word <11>
@loop move.b (a0)+,d4 ; <11>
add.l d4,d0 ;sum the HHSB <11>
move.b (a0)+,d4 ; <11>
add.l d4,d1 ;sum the MHSB <11>
move.b (a0)+,d4 ; <11>
add.l d4,d2 ;sum the MLSB <11>
move.b (a0)+,d4 ; <11>
add.l d4,d3 ;sum the LLSB <11>
cmpa.l a0,a1 ;at checksum area yet?
bne.s @checkTop ;no, see if at top
adda.l #16,a0 ;yes, skip over checksums
bra.s @loop ;and continue summing
@checkTop
cmpa.l a0,a2 ;end of ROM yet?
bgt.s @loop ;no, keep summing
@compare
IF forRomulator THEN ; <1.2>
TestInRam A0 ; are we running in RAM? <1.2>
bne.s @exit ; if so, force chksum good <1.2>
ENDIF ; <1.2>
@byte1 cmp.l (a1)+,d0 ;byte 0 expected checksum
beq.s @byte2
bset #0,d6 ;error, flag byte 0 checksum error
@byte2 cmp.l (a1)+,d1 ;byte 1 expected checksum
beq.s @byte3
bset #1,d6 ;error, flag byte 1 checksum error
@byte3 cmp.l (a1)+,d2 ;byte 2 expected checksum
beq.s @byte4
bset #2,d6 ;error, flag byte 2 checksum error
@byte4 cmp.l (a1)+,d3 ;byte 3 expected checksum
beq.s @exit
bset #3,d6 ;error, flag byte 3 checksum error
@exit RTS6 ;exit test
;---------------------------------------------------------------------------
; 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.l #0,d0 ;clear checksum accumulator <11>
moveq.l #0,d1 ;clear scratch <11>
WITH ROMHeader ; <12>
BigLea BaseOfROM,a0 ;point at ROM start, expected checksum <11><v1.6><2.1>
move.l ROMSize(a0),d3 ;get the size of the ROM (in bytes) <12><11>
subq.l #4,d3 ;subtract size of checksum <11>
move.l (a0)+,d4 ;load up expected checksum <11>
ENDWITH
@ROMLoop ; <11>
move.w (a0)+,d0 ;fetch a ROM word <11>
add.l d0,d1 ;add to checksum <11>
subq.l #2,d3 ;decrement by 2 bytes <11>
bne.s @ROMLoop ;continue until done <11>
nop ;some nops for debug (leave these here for emulator use)
nop ;some nops for debug
eor.l d4,d1 ;result should be zero
beq.s @exit ; <11>
IF forRomulator THEN ;if we're built for the romulator, we'd never pass<T5>
bra.s @exit ; therefore, force a good checksum <2.4><T5>
ENDIF ; <2.4>
move.w #$FFFF,d6 ;set a failed code in result register [A310>
@exit RTS6 ;and exit
;---------------------------------------------------------------------------
; 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 <4>
bne.s @1000 ;Error if ­ 0 <4>
addq.l #4,a2 ;Else, Increment a2 to point to next location <5><4>
subq.l #1,d2 ;count it
bne.s @60 ;until done
RTS6 ;return no error
@1000 or.l (a2),d6 ;or in bad bits
RTS6
;---------------------------------------------------------------------------
; AddrLineTest
;
; This test writes a pattern in each memory address according to its address bit,
; then reads each back and verifies the pattern in reverse.
;
; On entry: a6 = return address
;
; On exit: d6 = failed bits of an address location, or error result from SizeMem <8>
; d7.b = if ­ 0: bank number which failed (1 = bank A) <8>
; if = 0: Size memory failed; d6 contains the error from size mem <8>
; a6 = return address
; (sp) = pointer to memory location table
;
; Destroys a0-a3, d0, d5
;
;---------------------------------------------------------------------------
AddrLineTest
move.b #0,d7 ;Initialize the bank counter <8>
movea.l a6,a4 ;Save Return address <7><SM5>
BSR6 SizeMemory ;Size all of memory <7>
movea.l a4,a6 ;Restore the return address <7><SM5>
bne.s @VerError ;If size mem failed, error out <8>
move.l (sp),a0 ;move memory table pointer into a0 <7>
@NextBankFill
add.b #1,d7 ;Increment the bank counter <7>
move.l (a0)+,a1 ;Get the start addr of this bank <7>
cmpa.l #-1,a1 ;is this all the banks? <7>
beq.s @MemFilled ;go to check if so <7>
movea.l (a0)+,a2 ;Get length of bank <7>
move.l a1,(a1) ;Initialize the first location of the bank <7>
moveq.l #4,d5 ;Start storing from offset 4 <7>
@Fill move.l d5,a3 ;Get the starting offset <7>
adda.l a1,a3 ;Add the base addr of this bank <7>
move.l a3,(a3) ;write test data to test address <7>
lsl.l #1,d5 ;calculate next test data <7>
cmp.l a2,d5 ;see if done <7>
blt.s @Fill ;Continue if not <7>
bra.s @NextBankFill ;Else go to next bank <7>
; All banks now have the fill pattern. Verify this in the reverse direction <7>
@MemFilled
lea -4(a0),a0 ;point a0 to the 'end of chunk table' mark <7>
@NextBankCheck
sub.b #1,d7 ;Decrement the bank counter <7>
movea.l -(a0),a2 ;Get the bank size from the chunk table <7>
movea.l -(a0),a1 ;and the start address of this bank <7>
moveq.l #4,d5 ;Initialize the starting offset <7>
@adjust lsl.l #1,d5 ;Shift the test offset <7>
cmp.l a2,d5 ;Is it greater than the bank size? <7>
blt.s @adjust ;continue shifting if not <7>
@check lsr.l #1,d5 ;Adjust the offset <7>
move.l d5,d0 ;Calculate the test address <7>
add.l a1,d0 ; <7>
movea.l d0,a3 ; <7>
move.l (a3),d6 ;Get the test data <7>
eor.l d0,d6 ;Verify it <7>
bne.s @VerError ;Error out if not zero <7>
cmp.l #4,d5 ;was that the last location? <7>
bgt.s @check ;Continue checking if not <7>
tst.l d5 ;Have we tried an offset of zero yet? <7>
beq.s @CheckCont ;Continue if so <7>
moveq.l #0,d5 ;Else, let's try an offset of zero <7>
bra.s @check ; <7>
@CheckCont
cmpa.l (sp),a0 ;Are we done yet? <7>
bgt.s @NextBankCheck ;go on to next bank if not <7>
move.b #0,d7 ;Success! Zero out the bank counter <7>
@VerError ; <7>
RTS6 ;Return <7>
;---------------------------------------------------------------------------
; 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
RTS6 ;return to caller, no errors
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;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
RTS6 ;return to caller
; From here to next <3> flag below was added for Ericson
;---------------------------------
; Moving Inversions Test (BIT).
;---------------------------------
;
;
; Inputs: a0 = bottom memory area to test
; a1 = top of memory area to test + 1
; a6 = return to caller
;
; Output: d6 is the error accumulator.
;
MovInvTest
move.l a0,a5 ; save starting address
move.l a1,d3
sub.l a0,d3 ; size of block to test
@1 clr.l (a0)+ ;set the memory to zero.
sub.l #4,d3
bne @1
;
; TOP OF FORWARD LOOP
clr.l d1
move.w #4,d1 ;Address increment, start at 4
@2 move.l #0,a2 ;Address offset value
;
; TOP OF ADDRESS INCREMENT LOOP
@3 move.l a5,a0 ;Starting address
adda.l a2,a0 ;...plus offset
;
; TOP OF BIT SET LOOP
clr.l d2 ;Bit to set
clr.l d4 ;Expect pattern
@4 move.l a0,a3 ;Working start address
;
; TOP OF WORKING ADDRESS LOOP
@5 move.l (a3),d3 ;Read
cmp.l d3,d4 ;...same as expected?
bne @100 ;...no, flag as error
bset d2,d3 ;Set the test bit
move.l d3,(a3) ;...write, with test bit set
move.l (a3),d5 ;...read again
cmp.l d5,d3 ;...same as written?
bne @101 ;...no, flag as error
adda.l d1,a3
cmp.l a1,a3 ;At end of memory?
bmi @5
; BOTTOM OF WORKING ADDRESS LOOP
;
move.l d5,d4 ;New expect data
add.w #1,d2 ;Next bit
cmp.w #32,d2 ;...at end?
bne @4
; BOTTOM OF BIT SET LOOP
;
;
; TOP OF BIT CLR LOOP
clr.l d2 ;Bit to clear
move.l #$FFFFFFFF,d4 ;Expect pattern
@6 move.l a0,a3 ;Working start address
;
; TOP OF WORKING ADDRESS LOOP
@7 move.l (a3),d3 ;Read
cmp.l d3,d4 ;...same as expected?
bne @100 ;...no, flag as error
bclr d2,d3 ;Set the test bit
move.l d3,(a3) ;...write, with test bit set
move.l (a3),d5 ;...read again
cmp.l d5,d3 ;...same as written?
bne @101 ;...no, flag as error
adda.l d1,a3
cmp.l a1,a3 ;At end of memory?
bmi @7
; BOTTOM OF WORKING ADDRESS LOOP
;
move.l d5,d4 ;New expect
add.w #1,d2 ;Next bit
cmp.w #32,d2 ;...at end?
bne @6
; BOTTOM OF BIT CLR LOOP
;
adda.l #4,a2 ;Next address base offset
cmp.l d1,a2 ;...done all offsets?
bne @3 ;...no, continue
; BOTTOM OF ADDRESS INCREMENT LOOP
;
;
asl.l #1,d1 ;New Address increment value
cmp.l #$80000,d1 ;...at end?
bne @2 ;...no, continue
; BOTTOM OF FORWARD LOOP
@99 move.l a5,a0 ; restore starting address
rts6
;
@100 eor.l d3,d4 ;...same as expected
move.l d4,d6
bra @99
;
@101 eor.l d5,d3
move.l d3,d6
bra @99
; From here to next <3> flag above was added for Ericson
;---------------------------------------------------------------------------
; No Test implemented
;
;---------------------------------------------------------------------------
NoTest
moveq #0,d6
RTS6
ENDPROC