mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 01:49:19 +00:00
1153 lines
38 KiB
Plaintext
1153 lines
38 KiB
Plaintext
;
|
|
; 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
|
|
|