boot3/OS/StartMgr/USTTestMgr.a

3251 lines
122 KiB
Plaintext
Raw Normal View History

;
; File: USTTestMgr.a
;
; Contains: This file includes the Test Manager routines.
;
; Written by: Dave Holzer, Gary Rensberger
; Unmercifully
; Mutated by: Every new CPU we do
;
; Copyright: <09> 1983-1990, 1992-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM11> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
; machines.
; <SM10> 6/14/93 kc Roll in Ludwig.
; <LW6> 4/14/93 fau Changed the baud rate for the TestManager communication from
; 9600 to 19200.
; <LW5> 3/7/93 fau While storing results into PRAM, made sure that the whole
; register is cleared, even though only 1 byte is used. WrXByte
; for Cyclone had a problem with this not being so.
; <LW4> 3/6/93 fau Made sure that when running the memory test (cmd9) all access
; are non-cacheable and serialized. If not, writes to CUDA would
; not occur.
; <SM9> 01/07/93 HY Fix problem with XX test and all ROM based tests. The offset
; into the TestTable was off by 4 because 4 tests had been removed.
; TJR In MMUOff (*3 STM command) the data cache needed to be
; turned off because without the MMU the I/O area was being
; cached and this caused data to be read from the cache and
; not the physical device. Only the 68030 case was fixed.
; <SM8> 12/22/92 HY Fix a problem with serial test manager.
; <SM7> 11/16/92 fau When storing results to PRAM, I made sure that a CudaInit is
; done for CUDA machines, in order to set Cuda so it can respond
; to Rd/WrXByte. This is because the CudaManager has gone away
; (since we tested all the memory).
; <SM6> 11/3/92 rab Roll in Horror changes. Comments follow:
; <H13> 8/3/92 AL Fixed the TestManager cmd4 access to critical tests.
; <H12> 7/27/92 BG Fix SetupBases to not use A3 to save A6.
; <H11> 7/20/92 AL Fixed the TestManager cmd8 access to non-critical tests, fixed
; some comments.
; <H10> 7/1/92 AL Fixed the Serial Test Manager *N and *T commands, and the
; TestManager cmd4 and cmd6 functions, which were affected by
; moving this file to USTStartTest1.a (see comments at <H6>.
; <H9> 6/17/92 AL Added identifiers for a bunch of new machines to the table used
; by STM to fill out the *5 command. Updated the descriptions of a
; couple of existing entries in that table.
; <H8> 6/9/92 AL Changed StoreResults to preserve the return address in USP
; rather than A0 because the PG&E version of WrXByte trashes A0.
; <H7> 6/7/92 AL Fixed a couple of references to table-based data from longs to
; words (because the data is word length). Added DartanianLC to
; the table of machine identifiers used by STM. Removed a couple
; of unnecessary lines of code. Enhanced the NJump table to allow
; access to the SONIC tests for STM. Added some comments to
; existing code. Fixed the TestManager ATrap access mechanism for
; the TJump table because of problems that arose when this file
; was moved to a different link area (see comments under H6).
; <SM5> 9/25/92 RB Changed a few BSR6 macros to jumps.
; <SM4> 9/24/92 WS The jump table for the diagnostic test had been changed to use
; long jumps but the offset in the calling rountines still uses
; word offsets. Fixed this - actually borrow fix from horror.
; <SM3> 8/19/92 CSS Update from Reality:
; <43> 8/18/92 DTY Change the name of BootGlobs to StartGlobals to avoid confusion
; with BootGlobals, which is used by the boot code in Boot[1-3].a.
; <SM2> 5/16/92 kc Roll in Horror Changes.
; <H6> 3/6/92 AL Added support for the new CTE v2.1 kernel. Added a "new"
; TestManager routine at the end that takes care of handling CTE
; stuff for anybody that wants it to. After the conditionalized
; PROC mods made by jmp, it was discovered that the original
; USTStartTest.a had outgrown its allocated space in the ROM. So,
; I had to create a new file, USTSTartTest1.a, and moved this file
; and USTEnvirons.a into it. Added in support to access the new
; DBLite noncritical tests (PG&E Selftest and GSC registers test).
; Moved the PRAM routines RdXByte, WrXByte and ClkWpOff over to
; the file USTPram.a where they will be within BSR6 range of all
; the references to them from USTStartTest.a. There are a few
; references to them from USTStartTest1.a, but they can be
; converted to BigBSR6,a0 accesses.
; <H5> 01/27/92 jmp Conditionalized the PROC parts of this file for use in lining up
; the UST part of HORROR with that of TERROR/Zydeco.
; <H4> 11/25/91 CCH Use standard VIA equates.
; <H3> 11/6/91 SWC Universalized the RAM-less Power Manager routines. Modified the
; PRAM routines to call hardware-specific code thru a new table
; entry in the ProductInfo table. The hardware-dependent code is
; now in ClockPRAMPrimitives.a Removed SendToClk, ReadFrClk since
; they're no longer used.
; <H2> 10/23/91 jmp Updating from the Zydeco-TERROR project.
; <6> 4/22/91 BG Rolled in Scott Smyers changes: Fixed Atrap invoked RAM tests
; for Orwell machines. Also improved error reporting for ROM based
; RAM tests.
; <5> 4/13/91 BG Rolled in Scott Smyer's changes: Removed the diagROMEntry code
; and moved it to USTEnvirons.a. Added the 53C96 register test to
; the NJUMP table, along with some stubs for tests which are in
; the Apollo ROMs, but not Terror (these are placeholders to keep
; the test numbers consistent between all machines). Added the
; "get name" selector to the _TestManager Atrap.
; <4> 1/14/91 CCH Rolled in Scott Smyer's changes.
; <3> 12/14/90 HJR Added hook for CTE to serial test manager.
; <2> 9/17/90 CCH Modified data cache disable code to be 68040-friendly.
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; Pre-Terror ROM comments begin here.
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; <12> 6/14/90 CV Fixed cmd8 to use a1 and a0 so they're set up for the run time
; checks in RBV test and Egret test.
; <11> 5/31/90 BA Rolling in changes from Reality. Original comments below.
; {25} 5/30/90 SS Enhanced the version command so that it also returns the ROM
; version number, release number and machine number.
; {24} 5/30/90 SS Changed the restart command ('*I') so that it jumps to the
; restart vector, instead of just jumping to the start tests. The
; old way was causing problems on Egret based machines.
; {23} 5/21/90 SS Added a version command (*V) which returns the current version
; of the serial test manager to the serial port. Ericson/Elsie
; STM will be version 2.0; previous revisions do not support the
; version command and will respond with a ? indicating pre-2.0.
; <10> 5/16/90 JJ Rolling in changes from Reality.
; {22} 5/16/90 SS Changed some register usage at cmd4, 5, 6 and 9 initialization
; to be compatible with critical tests that test memory.
; {21} 5/7/90 SS Fixed the cmd9 RAM test so that if it's on an Elsie it uses the
; ElsieTMVectors and does not attempt to turn off the MMU.
; {20} 5/2/90 SS Fixed the *3 command so that it doesn't use RAM and so that it
; checks if it's on an 030 machine before playing with the MMU.
; <9> 4/27/90 CV Rolling in changes from mainproj. Original comments below.
; {19} 4/26/90 SS Don't set up TMvectors in RAM except when you come in through
; TMRestart - otherwise, it may be a memory failure that you're in
; the test manager! Also, restore the stack after running a
; critical test. Any failure of SizeMemory destroys a7!
; {18} 4/23/90 SS Replaced critical test 0 with sizememory again. This is
; required by some service software. Made the moving inversions
; test critical test #7 (was the new #0). Removed the new test
; *Q, which was the new size memory test.
; {17} 4/20/90 SS Changed the PRAM interface routines by removing some extra waits
; and also changed them to use equates from the EgretEqu.a file,
; as per suggestions which came up in the code review of 4/16/90.
; {16} 4/19/90 SS Fixed up some register usage and some inconsistancies in how the
; exception vectors were initialized on noncritical tests and on
; entry to the test manager. Also added support for the Elsie
; test manager vector table for critical tests.
; <8> 4/10/90 JJ Rolling in changes from mainproj. Original comments below.
; {15} 4/6/90 rle update service id boot string to include new machines (CPUs/LWs)
; {14} 4/3/90 SS Following the memory tests in cmd9 I now load the warm start
; constant into RAM where expected so that the non-critical tests
; are not run at startup. Before, any failure in the NC tests
; would obliterate some of the memory test results. Also cleaned
; some things up in cmd9 results reporting area to make things
; less ambiguous (word vs long register operations were being used
; interchangeably).
; {13} 3/27/90 SS Added a timeout for waiting for the first IRQ on the packet type
; byte of the PRAM read and write egret transactions. Also
; conditionalized the calls to TM_WAIT in storeresults, the delay
; is only necessary when talking to an Egret when you don't know
; if you've banged on the VIA recently.
; <7> 3/27/90 CV Fixed bug in RdxByte and WrxByte to prevent system from hanging
; in the middle of a transaction.
; <6> 3/27/90 CV Rolling in changes from mainproj. Original comments below.
; {12} 3/23/90 SS Made some additional adjustments to RDXBYTE and WRXBYTE to look
; for the case where the Egret has a pending operation at the
; start of a PRAM access. Also added new machines to the machine
; code table which the Test Manager uses to display a unique ASCII
; character for each mac.
; {11} 3/20/90 SS Cleaned up the Egret communication transactions in RDXBYTE and
; WRXBYTE.
; {10} 3/19/90 SS In RDXBYTE and WRXBYTE, I removed the delay that I used to have
; between sampling XcvrSession and sending the packet type. The
; packet type needs to go out in <25<32>S!
; <5> 3/12/90 CV Rolling in changes from mainproj. Original comments below.
; {9} 3/9/90 SS Fixed up the way I get VIA1 address from the product info
; record. Also fixed a register conflict in StoreResults.
; <4> 3/2/90 CV Replacing existing file with file from mainproj.
; <8> 2/27/90 SS Changed my PRAM interface support routine names to be specific
; to the test manager (previous names conflicted outside when I
; exported them). Also added the RPU, Egret and sound interrupt
; tests to the serial test manager test table.
; <7> 2/16/90 SS Added a flag to all statements which changed to support Ericson.
; <6> 2/15/90 SS Conditionalized the Egret PRAM interface routines properly.
; Also restored registers following sizemem for the serial test
; manager.
; <5> 2/13/90 MA Conditionalized the Egret based PRAM read/write code with
; onMac32.
; <4> 2/12/90 MA Changed crit. test table so that sizemem is replaced by the
; moving inversions RAM test. SizeMem is now Test Manager command
; *Q. USP now holds ptr to prodInfo table. Used to hold ptr to
; viaBase. Save/Restore A1/A2 between calls to tests. Changed
; RDXByte and WRXByte to work w/ EGRET.
; <2> 1/3/90 SES Changes made for Mark Appleman. Added FMCCacheTest to NJump
; table. Removed OSSCntrTest from NJump table.
; <2.9> 11/22/89 rle needed for ZoneV: move exception table into ROM for memory tests
; run
; <2.8> 11/21/89 MSH Power turn on turned on too much. Changed 2 haspowermgr to
; onhcmac, better feature based conditional descriptions.
; <2.7> 11/13/89 rle fixed one small bug when checking number of banks in cmd9
; <2.6> 11/13/89 SES Added diagnostics for FMC shift register, OSS registers, counter
; and interrupt.
; <2.5> 11/11/89 rle needed for ZoneV: fixed bugs inadvertantly introduced when
; rewriting STTestMgr--various fixes to serial test manager to
; keep interface the same as on previous CPUs, fixed trap test
; cmd9 to properly test memory, calling SizeMemory when the chunk
; table is blown away
; <2.4> 11/9/89 GMR Disabled cache before calling SizeMem in cmd9, so size memory
; properly sizes. Eliminated problem of memory test wiping out
; chunk table in cmd9 when doing more then 1 pass.
; <2.3> 11/1/89 GMR NEEDED FOR ZONE5: Setup a2 with VIA1 base before calling
; StoreResults, used by the TestManager trap. It previously used
; the VIA lowmem, which could be blown away during a RAM test.
; <2.2> 10/16/89 rle changed Aurora16 bootstring identifier to "A" so that it doesn't
; conflict with other identifiers previously assigned
; <2.1> 10/9/89 GMR Fixed conditional around cmd9 to fix Emacs build.
; <2.0> 10/7/89 GMR NEEDED FOR ZONE5: Cleaned up test manager trap interface, to
; make it universal, and not call GetHardwareInfo. Changed SizeMem
; glue routine to set d7.b = $FF if d6 contains error bitmask,
; otherwise, d7.b = 0 if d6 pts to memory chunk table.
; <1.9> 8/22/89 GMR Removed runtime machine check on entering Test Manager.
; <1.8> 7/15/89 GMR Setup exception table in RAM at start of test manager, so
; non-critical tests won't need to. Save universal registers
; around non-critical test calls (*N).
; <1.7> 6/26/89 GMR Added stub sizemem routine which returns pointer to chunk table
; in d6. Made U_TMRestart decide which test manager to call
; (Fremont's or universal)
; <1.6> 6/16/89 GGD Fixed echoing bug in the 'L' command.
; <1.5> 6/14/89 GMR Changed the timed system message to output proper code for
; system we're running on.
; <1.4> 6/13/89 GMR Added Gary D's fast Mod3Test and a shorter RomTest, in new file
; USTCritTests.a
; <1.3> 6/13/89 GGD Modified to work with latest version of Beep.a, leave cache on,
; pass VIA1 base to Beep calls in A5.
; <1.2> 6/11/89 GMR Fixed lea VBase to make universal in StoreResults.
; <1.1> 6/11/89 GMR Removed INCLUDES, now in header file which includes all others.
; <1.0> 6/11/89 GMR Added new universal StartTest files for first time to EASE.
; Based on Fremonts file 'TestMgr.a' version <2.0>.
;------------------------------------------------------------------------------
TMProc PROC ; <v1.1>
EXPORT SetVectorTable ; <2.1>
EXPORT SetupBases
EXPORT TestManager
EXPORT TMEntry1
EXPORT TMRestart
EXPORT StartTimer
EXPORT GetChar
EXPORT CvtAscii
EXPORT OutChar
EXPORT TJump ;<SM6>
IMPORT USTPmgrTurnOn
IMPORT USTPmgrSendCommand ;<H3>
IMPORT USTPMGRSendByte ;<H3>
IMPORT USTPMGRRecvByte ;<H3>
EXPORT TM_SendByte ;<8>
EXPORT TM_GetByte ;<8>
EXPORT TM_Wait ;<8>
IMPORT StartTest1
IMPORT JGetHardwareInfo
IMPORT StartTestFlags
IMPORT SizeMemory
IMPORT Mod3Test
IMPORT RevMod3Test
IMPORT RomTest
IMPORT DataBusTest
IMPORT AddrLineTest
IMPORT ExtRAMTest
IMPORT MovInvTest ;<7>
IMPORT SizeV8VRAM ;<35>
IMPORT NoTest
IMPORT SCCRegTest
IMPORT SCCLoopTest
IMPORT SCCTimerTest
IMPORT VIATest
IMPORT TestSCSI
IMPORT TestASC
IMPORT PramTest
IMPORT TestRBV
IMPORT TestSWIM
IMPORT Float_Test
IMPORT TestPGC
IMPORT FMCRegTest ;<2.6>
IMPORT FMCCacheTest ;<2>
IMPORT OSSRegTest ;<2.6>
IMPORT OSSIntTest ;<2.6>
IMPORT RPUTest ;<8>
IMPORT USTTests
IMPORT TMVectors ; <v1.1>
IMPORT ElsieTMVectors ; <16>
IMPORT SetSCCIOPBypass ; <v1.1>
IMPORT ErrorBeep4 ; <v1.1>
IMPORT EgretTest ;<8>
IMPORT TestSndInts ;<8>
IMPORT TestCLUT ;<27>
IMPORT TestVRAM ;<28>
IMPORT TestC96 ;<T5>
IMPORT TestGSCRegs
IMPORT PGESelfTest
IMPORT TestCSCRegs
IMPORT UTECmd ;<36>
IMPORT BaseOfRom
IMPORT CLKWPOFF,WRXBYTE,USTSUBTESTS,USTCPUList
CASE ON
IMPORT GI_InitInterface
IMPORT GI_GetVersion
IMPORT GI_AllocPermMem
IMPORT GI_AllocTempMem
IMPORT GI_FreeTempMem
IMPORT GI_GetCommentary
IMPORT GI_GetDefaultExecutionOptions
IMPORT GI_ExecuteDTM
IMPORT SONIC_Test ;SONIC Ethernet chip test <T4><SM6>
IMPORT SONIC_BitMarch ;SONIC Ethernet register bitmarch subtest <T4><SM6>
IMPORT SONIC_CAMDMA ;SONIC Ethernet on chip DMA subtest <T4><SM6>
IMPORT SONIC_Loopback ;SONIC Ethernet loopback subtest <T4><SM6>
CASE OFF
nuBusTTxlat EQU $00FFC040 ; require serialized writes <LW4> fau
ioNuBusTTxlat EQU $00FFC040 ; for all I/O space <LW4> fau
;))) [C660/22Jan87>[C703/30Jan87> DAH
EJECT
;---------------------------------------------------------------------------
; This is the Trap entry to the Test Manager. It is entered by a trap
; call _TestManager.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; On entry, D0 = the requested TestManager routine code, as follows:
;
; Any TestManager call that has a code less than $xxx10000 is
; considered to be an "old" style TestManager call. Anything with
; a code of $xxx10000 or greater is a "new" style call. A "new" style
; call will utilize CTE v2.1 (or greater) to execute DTMs. The user
; is free to mix and match, since there are no overlapping functions
; between the "old" and "new" TestManager functions. Here are the
; "new" TestManager codes and their corresponding functions:
;
; CTE routines accessible by the "new" TestManager:
; $xxx10000 GI_InitInterface
; $xxx10001 GI_GetVersion
; $xxx10002 GI_AllocPermMem
; $xxx10003 GI_AllocTempMem
; $xxx10004 GI_FreeTempMem
; $xxx10005 GI_GetCommentary
; $xxx10006 GI_GetDefaultExecutionOptions
; $xxx10007 GI_ExecuteDTM
;
; Utility routines accessible by the "new" TestManager:
; $xxx20000 Initialize the CTE interface for use with the TestManager
; $xxx20001 Get the info for a ROM-based test and subtest
;
; On entry to this routine, the first thing to do is check for
; "old" vs. "new". If it's new, then jump down to the new TM entry
; point. Otherwise, stay here and do the old stuff.
;
;
; These are the "old" TM codes (still supported, of course):
;
; $xxxx0000 for normal canned test request
; $xxxx0001 for RTS immediately, interrupts ON
; $xxxx0002 for RTS immediately, interrupts OFF
; $xxxx0003 for setup and jump to Test Manager
; $xxxx0004 for registers already prepped for test
; $xxxx0005 for like #0 but test number is a bit mask
; $xxxx0006 for like #4 but test number is a bit mask
; $xxxx0007 for PMgr systems only like #5 [v1.2>
; $xxxx0008 index is to non-critical tests (not a bit mask) <v1.0>
; $xxxx0009 for canned memory testing of discontiguous memory <v1.9>
;
; A0 = Pointer to Canned Test Request Block (CTRB)
;
; CTRB = Record
; Ops: integer; {test options}
; NumPass: integer; {test number/passes to run}
; RAMLow: Ptr; {RAM low address}
; RAMHigh: Ptr; {RAM high address}
; result: longint; {test result} <v2.1>
; mask: integer; {mask of tests to run} <v2.1>
; End;
;
; Options word =
; Bit 12 = stop on first failure and exit
; Bit 13 = loop on any failure forever
; Bit 14 = store test results clock parameter RAM
; Bit 15 = boot when done testing
;
; Test bit #15 (test 7) is used to force the test count through one more loop
; of all tests. Kinda hokey but there seems to be a register shortage in this
; here machine.
;
; If the boot when done testing bit is not set, then return is via an RTS
; after restoring all registers.
;
; If the boot when done testing bit is set, then no direct return is done,
; but the system is rebooted.
;
; For commands #4 and #6, registers are assumed to be correctly set up
; on entry for the test(s) to run. The required registers may depend on the
; test(s) to be executed, but generally the following is true:
;
; a0 = pointer to low memory address for RAM test
; a1 = pointer to high memory address for RAM test
; d7 = options set up according to the bits defined in this file
; and test/pass count in d7.w
; d6 = 0, prepped for error codes
;
; For commands #5 and #6, the test number is assumed to be a bit mask of
; the tests to run consecutively. This option is for queuing up RAM tests.
; The command #5 is like command #0 and #6 is like #4 in the method
; used to set up the registers.
;
;---------------------------------------------------------------------------
CTEAtrap equ $10000 ; a value in d0 greater than or equal to this
; indicates that this is a "new" style TM call
TestManager
cmp.l #CTEAtrap,d0 ; all function calls LOWER than this
bge.l NewTMCall ; call the old test manager, if appropriate
movem.l d1-d5/a0-a6,-(sp) ; save regs (except d6,d7)
move.w sr,-(sp) ; save current SR
or.w #HiIntMask,sr ; disable all ints but NMI for all cpu's
movec VBR,a2 ; get old VBR
move.l a2,-(sp) ; save it
suba.l #VTEntries*4,sp ; put VBR below stack
move.l d0,d3 ; save d0
movea.l a0,a3 ; save a0
movea.l a1,a4 ; save a1
movea.l sp,a1 ; put VBR at current stack
BSR6 SetVectorTable ; Setup our exception table in RAM (a2=VBR)
move.l d3,d0 ; restore d0
movea.l a3,a0 ; restore a0
movea.l a4,a1 ; restore a1
lea TestMgrCmds,a2 ; point to the command dispatch table
cmp.w (a2)+,d0 ; range check the command number
bhs.s TestMgrExit ; if out of range, just return
add.w d0,d0 ; command*2 to index into table
adda.w 0(a2,d0.w),a2 ; point to the routine
jmp (a2) ; execute the command
;_________________________________________________________________________________
TestMgrExit ; done with trap, exit back to caller
adda.l #VTEntries*4,sp ; dump vector table
movea.l (sp)+,a2 ; get saved VBR
movec a2,VBR ; restore it
move.w (sp)+,sr ; restore SR
movem.l (sp)+,d1-d5/a0-a6 ; restore registers we trashed
rts
;_________________________________________________________________________________
TestMgrCmds
dc.w (@End-@Start)/2 ; number of table entries
@Start
dc.w cmd0 -@Start ; Command #0, normal canned test request
dc.w cmd1 -@Start ; Command #1, RTS immediately, ints ON
dc.w cmd2 -@Start ; Command #2, RTS immediately, ints OFF
dc.w TMEntry0-@Start ; Command #3, setup and jump to Test Manager
dc.w cmd4 -@Start ; Command #4, registers already prepped for test
dc.w cmd5 -@Start ; Command #5, like #0 but test number is a bit mask
dc.w cmd6 -@Start ; Command #6, like #4 but test number is a bit mask
IF hasPowerMgr THEN ;if on portable
dc.w cmd7 -@Start ; Command #7, for PMgr systems only like #5
ELSE
dc.w TestMgrExit-@Start ; Command #7, unused on this system
ENDIF
dc.w cmd8-@Start ; Command #8, index is to non-critical tests (not a bit mask)
dc.w cmd9-@Start ; Command #9, complete RAM test, reboot on exit
dc.w TestName-@Start ;Command #10, return a test name <T5>
dc.w NubMgrDispatch-@Start ; Command #11, dispatch to the nub manager <32>
@End
;_________________________________________________________________________________
cmd2
ori.w #HiIntMask,(VTEntries+1)*4(sp) ; disable interrupts in saved SR
cmd1 bra.s TestMgrExit ; restore state and return
;_________________________________________________________________________________
; Process command #0, execute a canned test request
cmd0 clr.l d6 ;clear error register
move.l Ops(a0),d7 ;load test options/test/passes
move.l RAMHigh(a0),a1 ;point to RAM high if RAM test
move.l RAMLow(a0),a0 ;point to RAM low if RAM test
;_________________________________________________________________________________
; Now d7 has the options bits, the test number, and the passes to run
; Entry to this point either from above or a command #4
cmd4 move.w d7,d1 ;get test number
lsr.w #8,d1 ;isolate test number
; cmp.w MaxTest,d1 ;is legal test request?
and.l #$0000ffff,d1 ;mask off everything except test number <H10><SM4>
cmp.l MaxTest,d1 ;is legal test request? <H10><SM4>
bge.s TestMgrExit ;not legal, exit to caller
movea.l UnivInfoPtr,a2 ;Get the Universal info pointer <22>
move.l a2,USP ;Put it in the User Stack Pointer <22>
; add.w d1,d1 ;adjust for table access
; lea TJump,a5 ;point to test jump table
; adda.w 0(a5,d1.w),a5 ;point to test
lsl.l #2,d1 ;adjust for longword table access <H13><SM4>
lea TJump,a5 ;point to test jump table<SM4>
move.l (a5,d1.l),d1 ;fetch test offset from table <H13><SM4>
lea (a5,d1.l),a5 ;point to test <H13><SM4>
@loop lea @1,a6 ; setup return address <SM5> rb
jmp (a5) ;execute requested test <SM5> rb
@1 ; <SM5> rb
tst.l d6 ;any errors this test?
beq.s @noErr ;no, continue
btst #loop,d7 ;Error, wants to loop?
bne.s TestLoop ;yes
btst #stop,d7 ;want stop on error?
bne.s StopTest ;yes
@noErr subq.b #1,d7 ;decrement passes to run
bne.s @loop ;not done testing
StopTest
btst #pram,d7 ;wants to store results in clock?
beq.s @noStore ;no
move.l USP,a1 ;Get UnivInfoPtr <7>
movea.l ProductInfo.DecoderInfoPtr(a1),a2 ; <7>
adda.l a1,a2 ;Add base to get target address <9>
movea.l DecoderInfo.VIA1Addr(a2),a2 ;Get VIA1 base <7>
BSR6 StoreResults
@noStore
btst #boot,d7 ;wants to boot when done?
beq.s TestMgrExit ;no, just RTS as normal
BigJmp BaseOfRom+ROMHeader.ReStart,a0 ; address of restart routine [v1.3> <v1.0><1.4>
TestLoop
lea TestLoop,a6
jmp (a5) ;execute test forever...
;_________________________________________________________________________________
; Process command #5, test number is a bit mask
cmd5 clr.l d6 ;clear error register
move.l Ops(a0),d7 ;load test options/testmask/passes
move.l RAMHigh(a0),a1 ;point to RAM high if RAM test
move.l RAMLow(a0),a0 ;point to RAM low if RAM test
;_________________________________________________________________________________
; Now d7 has the options bits, the test number bit mask, and the passes
; to run. Entry to this point either from above or a command #6
cmd6 moveq.l #0+8-1,d1 ; d1 is bit number (test number + 8) in the <H7><SM6>
; test bit field of d7. It is the test number <H7><SM6>
; + 8 because the test bit field is in the <H7><SM6>
; second byte of d7 (bits 8 - 15), so we need <H7><SM6>
; to add 8 to the bit number.
movea.l UnivInfoPtr,a2 ; get the universal info pointer <22> <H7><SM6>
move.l a2,USP ; save it for PRAM routines <22> <H7><SM6>
@next addq.l #1,d1 ; next test number
cmpi.w #15,d1 ; see if all tests run
bgt.s @cntPass ; exit if so
btst.l d1,d7 ; do we want to run this test
beq.s @next ; if not, try next one
; add.w d1,d1 ;adjust for table access (test num + 8)*2
; lea TJump,a5 ;point to test jump table
; adda.w -16(a5,d1.w),a5 ;point to test
; add.w d1,d1 ; adjust for table indexing (test num + 8)*4
; lea @return-32(d1.w),a6 ; setup return address
; jmp (a5) ;execute requested test
lsl.l #2,d1 ; adjust for long word table access (test num + 8)*4 <H7><SM4>
lea TJump,a5 ; point to test jump table <H7><SM4>
adda.l -32(a5,d1.l),a5 ; point to test (remember to subtract out the " + 8 * 4" <H7><SM4>
; included in the lsl.l above) <H7><SM4>
lea @return-32(d1.l),a6 ; setup return address <H7><SM4>
jmp (a5) ; execute requested test <H7><SM4>
@return
moveq.l #0+8,d1 ; return from test number 0, bit 8
bra.s @checkErrors ; check for errors
moveq.l #1+8,d1 ; return from test number 1, bit 9
bra.s @checkErrors ; check for errors
moveq.l #2+8,d1 ; return from test number 2, bit 10
bra.s @checkErrors ; check for errors
moveq.l #3+8,d1 ; return from test number 3, bit 11
bra.s @checkErrors ; check for errors
moveq.l #4+8,d1 ; return from test number 4, bit 12
bra.s @checkErrors ; check for errors
moveq.l #5+8,d1 ; return from test number 5, bit 13
bra.s @checkErrors ; check for errors
moveq.l #6+8,d1 ; return from test number 6, bit 14
bra.s @checkErrors ; check for errors
moveq.l #7+8,d1 ; return from test number 7, bit 15
* bra.s @checkErrors ; check for errors
@checkErrors
tst.l d6 ;any errors on last test?
beq.s @next ;no, go to next test
; Error encountered, check for loop and stop on error options
btst #loop,d7 ;wants loop on error?
bne.s TestLoop ;yes
btst #stop,d7 ;want stop on error?
bne.s StopTest ;yes
; One pass through all tests requested done, any errors processed
@cntPass
subq.b #1,d7 ;decrement passes to run
bne.s cmd6 ;not done testing
bclr #15,d7 ;see if doubling the pass count
bne.s cmd6 ;force another pass through
bra.w StopTest ;done testing
; ))) [C129/16Sep86> DAH
;))) russ <v1.0>
;--------------------------------------------------------------------------- <v1.0>
; <v1.0>
; Test Manager Command 8: This is the method used to access the non-critical <v1.0>
; tests through the NJump test table. Since there are more than 8 (and are <v1.0>
; likely to be more than 16) tests available here, they are only available one <v1.0>
; at a time--a bit mask is not used. The upper word of d7 is still reserved for <v1.0>
; various flag bits, such as stop on error or loop on error. (These are the only <v1.0>
; two flags supported within this command.) The upper byte of the lower word <v1.0>
; of d7 is a numerical index into the NJump test table, while the lower byte <v1.0>
; is the number of passes. Note that this structure allows for 128 tests which <v1.0>
; can run for up to 256 passes one at a time. <v1.0>
; <7>
; On entry: <7>
; a0 = pointer to the CTRB. <7>
; <v1.0>
;--------------------------------------------------------------------------- <v1.0>
cmd8 clr.l d6 ;clear error register <v1.0>
move.l Ops(a0),d7 ;load test options/testmask/passes <v1.0><7>
@loop move.l d7,d1 ;move working copy of testmask <v1.0>
lsr.w #8,d1 ;shift mask into byte position <v1.0>
sub.w #$84,d1 ;subtract out non-crit offset <v1.7><SM9><HY>
; cmp.w MaxNTst,d1 ;is valid test number? <v1.0>
and.l #$0000ffff,d1 ;mask off all but the test number <H10><SM4>
cmp.l MaxNTst,d1 ;is valid test number? <v1.0><H10><SM4>
bge.s @exit ;invalid, exit to caller <v1.0>
; add.w d1,d1 ;adjust for table index <v1.0>
; lea NJump,a5 ;point to test jump table <v1.0>
; adda.w 0(a5,d1.w),a5 ;point to test <v1.0>
asl.l #2,d1 ;adjust for table index <v1.0><H10><SM4>
lea NJump,a5 ;point to test jump table <v1.0><H10><SM4>
move.l (a5,d1.l),d1 ;fetch test offset from table <H11><SM4>
lea (a5,d1.l),a5 ;point to test <H11><SM4>
@test movea.l UnivInfoPtr,a1 ;get lowmem UnivInfoPtr. <26><7>
movea.l a1,a0 ;get univinfoptr into a0 also <26>
adda.l ProductInfo.DecoderInfoPtr(a0),a0 ; ptr to base addresses <26>
move.l AddrMapFlags,d0 ;base addr valid bit mask <7>
move.w ProductInfo.ProductKind(a1),d2 ; get the BoxFlag value <26><5.8><7>
lea @1,a6 ; setup return address <SM5> rb
jmp (a5) ;execute requested test <v1.0><SM5> rb
@1 ; <SM5> rb
tst.l d6 ;any errors last test? <v1.0>
beq.s @cntPass ;no, count a pass.... <v1.0>
btst #loop,d7 ;error, wants to loop ? <v1.0>
bne.s @test ;yes, test again <v1.0>
btst #stop,d7 ;want stop on error? <v1.0>
bne.s @exit ;yes <v1.0>
@cntPass
subq.b #1,d7 ;decrement passes to run <v1.0>
bne.s @loop ;not done testing <v1.0>
@exit bra.w TestMgrExit ; restore state and return
;--------------------------------------------------------------------------- <v1.9>
; <v1.9>
; Test Manager Command 9: This is the method used to test memory on systems <v1.9>
; with discontiguous memory. Currently, this means MDU-based machines (Aurora <v1.9>
; and Four Square) and early versions of F-19. The process is as follows: <v1.9>
; SizeMem is called to establish the location of the first bank of memory. <v1.9>
; That bank is then tested with mod3, revmod3, and extram tests. SizeMem is <v1.9>
; called again to establish the presence of any additional banks of ram, and if <v1.9>
; they exist, they are tested the same way. Low bank results (register d6) are <v1.9>
; stored in bytes 252-255 of parameter ram, while high bank results are placed <v1.9>
; in bytes 244-247. The system is rebooted upon exit. <v1.9>
; <v1.9>
;--------------------------------------------------------------------------- <v1.9>
CAWA equ 13 ;CACR WA bit for 030 CPUs <20>
cmd9 clr.l d6 ;clear error register <v1.9><2.1>
move.l Ops(a0),d7 ;load test options/passes <v1.9>
; <34>
BigLea ElsieTMVectors,a3 ;First see if we are on an Elsie <21>
BigLea StartTest1,a4 ;Get the address of the start vector <21>
cmpa.l 4(a3),a4 ;Does this agree with where we are? <21>
beq.s @onElsie ;Continue if so <21>
BigLea TMVectors,a3 ;Otherwise, load the default TM vectors <21>
@onElsie ; <21>
movec a3,VBR ;VBR points to our exception table <21>
movec cacr,d0 ;First lets make sure we're not on an 020 box <21>
move.l d0,d1 ;Save the contents of the cacr register <21>
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <T2>
bset.l #15,d0 ; set the 040 CACR[DE] bit to see if on an 040>
movec d0,CACR ; see if the 040 CACR[DE] bit sticks
movec CACR,d0 ;
btst.l #15,d0 ; are we on an 040?
bne.s @onAn040 ; IF we're not on an 040 THEN
bset.l #CAWA,d0 ; Set the Write allocate bit (020s don't have this)
movec d0,cacr ; move it into the CACR <21>
movec cacr,d0 ; read it back <21>
movec d1,cacr ; restore the cacr <21>
btst.l #CAWA,d0 ; See if we were able to set the WA bit <21>
beq.s @not030 ; IF we're on a 68030 THEN
lea -4(sp),sp ; make room on the stack <21>
pmove.l TC,(sp) ; read logical address mode of MMU <21
move.l (sp),d0 ; Put the value in a data register <21>
bclr.l #31,d0 ; Turn off MMU enable bit <21>
move.l d0,(sp) ; move it back to memory <21>
pmove.l (sp),TC ; Load it into the MMU register <21>
lea 4(sp),sp ; pop off the space
@not030 ; ELSE
movec cacr,d0 ; get cache value
bclr #8,d0 ; disable the data cache
movec d0,cacr ; do it
bra.s @begin ; and move on
@onAn040 ; ELSE
; Revamped this routine a little. Made sure that the transparent translation registers <LW4> fau
; make all i/o space non-cacheable and serialized. <LW4> fau
MACHINE MC68040 ; required for the below instructions
cpusha bc ; make sure caches are invalidated <LW4> fau
sub.l d0,d0 ; clear d0 <LW4> fau
movec d0,CACR ; disable both instruction and data caches <LW4> fau
movec d0,TC ; make sure that the MMU is disabled <LW4> fau
move.l #nuBusTTxlat,D0 ; get value to translate upper nuBus space <LW4> fau
movec d0,DTT0 ; use serialized writes on this space <LW4> fau
movec d0,ITT0 ; use serialized writes on this space <LW4> fau
move.l #ioNuBusTTxlat,D0 ; get value to translate i/o and nuBus space <LW4> fau
movec d0,DTT1 ; use serialized writes on this space <LW4> fau
movec d0,ITT1 ; use serialized writes on this space
MACHINE MC68030 ; return to previous MACHINE directive
; ENDIF <T2>
@begin ; <v1.9>
BigBSR6 SizeMemory,a0 ;Size memory and set up the stack <16>
movea.l (sp),sp ;keep ptr to chunk table in sp <T6>
movea.l sp,a4 ;and keep the working copy in a4 <T6>
clr.l d6 ;clear out error register <v1.9>
@testm movea.l (a4)+,a0 ;bottom of memory to be tested <v1.9>
movea.l a0,a1 ;set up top of memory <v1.9>
adda.l (a4)+,a1 ;top of memory to be tested next first bank <T6>
BigBSR6 Mod3Test,a2 ;go launch Mod3Test <v1.9>
tst.l d6 ;any errors on last test? <v1.9>
bne @error ;yes, go process errors <v1.9>
BigBSR6 RevMod3Test,a2 ;go launch RevMod3Test <v1.9>
tst.l d6 ;any errors on last test? <v1.9>
bne @error ;yes, go process errors <v1.9>
BigBSR6 ExtRAMTest,a2 ;go launch ExtRAMTest <v1.9>
tst.l d6 ;any errors on last test? <v1.9>
bne @error ;yes, go process errors <v1.9>
BigBSR6 SizeMemory,a0 ;Size memory and set up the stack <16>
movea.l (sp),sp ;keep ptr to chunk table in sp <T6>
clr.l d6 ;clear out error register <T6>
cmpi.l #-1,(a4) ;does another bank exist? <v2.5>
bne @testm ;yep, go do it!!! <v1.9>
bra @pass ;one pass completed!!! <v1.9>
;--------------------------------------------------------------------------- <v1.9>
; Error encountered, check for loop and stop on error options <v1.9>
;--------------------------------------------------------------------------- <v1.9>
@error btst #loop,d7 ;wants loop on error? <v1.9>
beq.s @stp ;no <v1.9>
@loop lea @loop,a6 ; <v1.9>
jmp (a5) ;execute test forever... <v1.9>
@stp btst #stop,d7 ;want stop on error? <v1.9>
bne.w @done ;yes <v1.9>
; One pass through all tests done, any errors processed <v1.9>
@pass subq.b #1,d7 ;decrement passes to run <v1.9>
bne.w @begin ;not done testing <v1.9>
bclr #15,d7 ;see if doubling the pass count <v1.9>
bne.w @begin ;force another pass through <v1.9>
; We either exhausted the passes to run counter or stopping on an error <v1.9>
@done btst #pram,d7 ;wants to store results in clock? <v1.9>
beq.s @boot ;no <v1.9>
moveq.l #0,d2 ;Assume nothing about this machine <34>
BigBSR6 JGetHardwareInfo,a0 ; <35>
movea.l DecoderInfo.VIA1Addr(a0),a2 ;Get VIA1 base <34><2.3><3.1><7>
suba.l sp,a4 ;get the offset into the chunk table <T6>
move.l a4,d2 ;we need to work in this value <T6>
lsl.w #5,d2 ;effectively shift right by 3 and left by 8 (bank # in high byte)<T6>
swap d7 ;get high word of d7 <T6>
move.w d2,d7 ;replace it with the bank number <T6>
swap d7 ;and put it back in the high word <T6>
BSR6 StoreResults ; <T6>
@boot move.l #WmStConst,StartGlobals.sgWarmStart(sp) ;<SM3> CSS make this a warm start to preserve PRAM <14>
BigJmp BaseOfRom+ROMHeader.ReStart,a0 ;jump to restart routine <v1.9><2.2>
;---------------------------------------------------------------------------
; This routine stores the test results in the clock parameter RAM. This
; RAM has a total of 256 bytes, of which the last 16 bytes belong to
; Test Engineering. The current usage is as follows:
;
; bytes 240-243 = results from register D7
; bytes 244-247 = results from register D6
; bytes 248-249 = $4448 = results from MacPP, $5448 = results from NuMac
; bytes 250-251 = check sum word validating what is in 240-247
; bytes 252-255 = used by RAM based tests.
;
; Entry via BSR6
;
; Registers used: d0,d1,d2,d3,d4,a0,a1,a2,a4,a6
;---------------------------------------------------------------------------
IMPORT CudaInit
StoreResults
move.l a6,USP ;save return address <9><H8>
; CudaInit implies a SyncAck cycle which synchronizes Cuda to the system and disables
; all asynchronous messages sources (Auto Poll, RTC, Power Messages, Unknown). No further
; individual disabling of asynchronous message sources is required. (R. Montagne 5/25/92)
;
; d0 should contain the Flags indicated which base addresses are valid, from HardwareInfo
move.l d0,d3 ; save a copy of d0
move.l #EgretFWMask,d0 ; mask for Egret Firmware
and.l d1,d0 ; isolate the field
sub.l #Egret8,d0 ; see if we have Egret FW
beq.w @CudaDone ; do Egret 8 or Caboose FW INIT, LC/si
sub.l #Egret8,d0 ; see if we have Caboose FW
beq.s @CudaDone ; do Caboose FW Init (same as Egret8)
sub.l #Egret8,d0 ; see if we have Cuda FW
bne.s @CudaDone ; if not, just exit
BigBSR6 CudaInit ;Setup Cuda Sysnc Ack with System
@CudaDone
BigBSR6 ClkWpOff,a4 ;turn write protect off clock chip
clr.l d4 ;clear for checksum
move.l #240,d3 ;start at byte 240 <v1.1>
@loop1
clr.l d1 ;Make sure that the registers we pass to the WrXByte <LW5> fau
clr.l d2 ;are clear on the upper bytes. It needs them like so <LW5> fau
rol.l #8,d7 ;align msb to send first
move.b d7,d2 ;get data byte to send
move.b d3,d1 ;get address byte to send
BSR6 TM_WAIT ;Delay a min of 300<30>s before writing <13>
BSR6 TM_WAIT ;to PRAM <13>
BigBSR6 WrXByte,a4
addq.w #1,d3 ;bump to next byte
cmp.w #244,d3 ;done with d7? <v1.1>
blt.s @loop1 ;no
@loop2 rol.l #8,d6 ;align msb to send first
move.b d6,d2 ;get data byte to send
move.b d3,d1 ;get address byte to send
BigBSR6 WrXByte,a4
addq.w #1,d3 ;bump to next byte
cmp.w #248,d3 ;done with d6? <v1.1>
blt.s @loop2 ;no
move.l #$54480000,d5 ;setup special bytes
move.w d4,d5 ;include checksum
move.l d5,d4 ; <7>
@loop3 rol.l #8,d4 ;align msb to send first <7>
move.b d4,d2 ;get data byte to send <7>
move.b d3,d1 ;get address byte to send
BigBSR6 WrXByte,a4
addq.w #1,d3 ;bump to next byte
cmp.w #12,d3 ;done with d3? <7>
blt.s @loop3 ;no
move.l USP,a0 ;restore return address <H8>
jmp (a0) ;return to caller <9>
;--------------------------------------------------------------------------- <T5>
; <T5>
; This is _TestManager selector number 10. It's function is to return a <T5>
; ROM test name given the test number (i.e., the test number reported <T5>
; in the diagnostic PRAM area).
;
; Aaron Ludtke 11/5/91
; Note that for the Horror ROM, the name strings were changed to pStrings from
; cStrings. I did this because it makes it more convenient to get the name info
; from the Serial Test Manager if you know the address of a string (pString) and
; can determine the length of the info to download across the serial port.
; <T5>
;--------------------------------------------------------------------------- <T5>
TestName ; <T5>
WITH USTSubtest, USTTest ; <T5>
move.w Ops(a0),d1 ;get the subtest number <T5>
ext.l d1 ;make it a long <T5>
BigLea USTSubtests,a1 ;get the address of the subtests table <T5>
move.w #sizeofUSTSubtest,d2 ;get the size of the subtest list <T5>
tst.w NumPass(a0) ;is this a test number, or subtest number? <T5>
beq.s @Subtest ;branch if this is a subtest <T5>
BigLea USTTests,a1 ;else, load the test table <T5>
move.w #sizeofUSTTest,d2 ;and the size of the test list <T5>
@Subtest
move.l a1,d6 ;start with the address of the table <T5>
@SearchLoop
cmp.l TTest_ID(a1),d1 ;is this our subtest? <T5>
beq.s @Foundit ;branch if so <T5>
adda.w d2,a1 ;else, go to the next entry <T5>
cmp.l #-1,TTest_ID(a1) ;are we at the end? <T5>
bne.s @SearchLoop ;continue if not <T5>
moveq.l #0,d6 ;return with a zero pointer <T5>
bra.s @exit ;and exit <T5>
@Foundit
add.l TNamePtr(a1),d6 ;dereference the name pointer <T5>
ENDWITH
@exit
bra TestMgrExit ;return to caller <T5>
;===========================================================================
; TestTable is a set of pointers to the canned test routines living in
; the System ROM. This table is accessed by the Test Manager when it
; receives a "T" command, followed by a test number, which is an index
; into this table.
;
; Note that only 7 'critical' tests are available from the TJump
; TestTable. (Ex: *T000400010000 will run ROMTest for one pass)
;
; NOTE: Because this file (USTTestMgr.a) was moved over to a the overpatch
; USTStartTest1.a file, the dc.w references to functions in USTCritTests.a
; and USTNonCritTests.a are too short. The references need to be changed
; to dc.l, but I'm not sure what effect it will have on the code. So, I
; need to go through and thoroughly test everything. AARON AARON
;
;---------------------------------------------------------------------------
; <20><><EFBFBD>TJump dc.w SizeMem-TJump ;Test #0 = SizeMemory <18>
; <20><><EFBFBD> dc.w DataBusTest-TJump ;Test #1 = DataBusTest
; <20><><EFBFBD> dc.w Mod3Test-TJump ;Test #2 = Mod3Test <1.4>
; <20><><EFBFBD> dc.w AddrLineTest-TJump ;Test #3 = AddrLineTest
; <20><><EFBFBD> dc.w RomTest-TJump ;Test #4 = ROMTest <1.4>
; <20><><EFBFBD> dc.w RevMod3Test-TJump ;Test #5 = RevMod3Test <1.4>
; <20><><EFBFBD> dc.w ExtRAMTest-TJump ;Test #6 = ExtRAMTest
; <20><><EFBFBD> dc.w MovInvTest-TJump ;Test #7 = MovInvTest <18>
; <20><><EFBFBD> dc.w SizeV8VRAMShell-TJump ;Test #8 = Size the Video RAM <35>
; <20><><EFBFBD> dc.w NoTest-TJump ;Test #9 = NoTest
; <20><><EFBFBD>MaxTest dc.w (*-TJump)>>1 ;Max test number <18>
TJump dc.l SizeMem-TJump ;Test #0 = SizeMemory <18>
dc.l DataBusTest-TJump ;Test #1 = DataBusTest
dc.l Mod3Test-TJump ;Test #2 = Mod3Test <1.4>
dc.l AddrLineTest-TJump ;Test #3 = AddrLineTest
dc.l RomTest-TJump ;Test #4 = ROMTest <1.4>
dc.l RevMod3Test-TJump ;Test #5 = RevMod3Test <1.4>
dc.l ExtRAMTest-TJump ;Test #6 = ExtRAMTest
dc.l MovInvTest-TJump ;Test #7 = MovInvTest <18>
dc.l SizeV8VRAMShell-TJump ;Test #8 = Size the Video RAM <35>
dc.l NoTest-TJump ;Test #9 = NoTest
;MaxTest dc.l (*-TJump)>>1 ;Max test number <18>
MaxTest dc.l (*-TJump)>>2 ;Max test number <18><H10><SM4>
;---------------------------------------------------------------------------
; TestTable is a set of pointers to the canned test routines living in
; the System ROM. This table is accessed by the Test Manager when it
; receives a "N" command, followed by a test number, which is an index
; into this table.
;
; Note that up to 128 (0-$7f) 'non-critical' tests are available from the NJump
; TestTable. (Ex: *N008600020000 will run SCCTimerTest for two passes)
;---------------------------------------------------------------------------
NJump dc.l SCCRegTest-NJump ;test #84 = SCCRegTest
dc.l SCCLoopTest-NJump ;test #85 = SCCLoopTest
dc.l SCCTimerTest-NJump ;test #86 = SCCTimerTest
dc.l VIATest-NJump ;test #87 = VIATest
dc.l TestSCSI-NJump ;test #88 = SCSITest
dc.l TestASC-NJump ;test #89 = SndTest
dc.l PramTest-NJump ;test #8A = PramTest
dc.l TestRBV-NJump ;test #8B = TestRBV
dc.l TestSWIM-NJump ;test #8C = TestSWIM
dc.l Float_Test-NJump ;test #8D = Float_Test
dc.l TestPGC-NJump ;test #8E = TestPGC
dc.l FMCRegTest-NJump ;test #8F = FMCRegTest <2.6>
dc.l FMCCacheTest-NJump ;test #90 = FMCCacheTest <2>
dc.l OSSRegTest-NJump ;test #91 = OSSRegTest <2.6>
dc.l OSSIntTest-NJump ;test #92 = OSSIntTest <2.6>
dc.l RPUTest-NJump ;test #93 = RPUTest <8>
dc.l EgretTest-NJump ;test #94 = EgretTest <8>
dc.l TestSndInts-NJump ;test #95 = TestSndInts <8>
dc.l TestCLUT-NJump ;test #96 = TestCLUT <27>
dc.l TestVRAM-NJump ;test #97 = TestVRAM <28>
dc.l TestPWM-NJump ;test #98 = in Apollo ROM only <T5>
dc.l TimeSoundInts-NJump ;test #99 = in Apollo ROM only <T5>
dc.l TestC96-NJump ;test #9A = TestC96 <T5>
CASE ON ; this is for the SONIC test names - they're C functions
dc.l SONIC_BitMarch-NJUMP ;test #9B = SONIC_BitMarch <H7><SM6>
dc.l SONIC_CAMDMA-NJUMP ;test #9C = SONIC_CAMDMA <H7><SM6>
dc.l SONIC_Loopback-NJUMP ;test #9D = SONIC_Loopback <H7><SM6>
CASE OFF
dc.l TestGSCRegs-NJump ;test #9E = TestGSCRegs <H7><SM6>
dc.l PGESelfTest-NJump ;test #9F = PGESelfTest <H7><SM6>
dc.l TestCSCRegs-NJump ;test #A0 = TestCSCRegs <H14>
MaxNTst dc.l (*-NJump)>>2 ;maximum number of tests available <H10><SM6>
TestPWM ; <T5>
TimeSoundInts ; <T5>
moveq.l #-1,d6 ;These tests are not in this ROM, indicate test does not apply <T5>
RTS6 ;and return <T5>
EJECT
;==================================================================================
;Universal Test Manager
;---------------------------------------------------------------------------
; NuMac ROM resident Test Manager for service and board burn in and any
; power up test failure. The Test Manager entry points are used
; as follows:
;
; TMEntry0 = Entry from _TestManager trap command or NMI.
; TMRestart = entry point from CritErr.
; TMEntry1 = entry point for board burn in.
;
;---------------------------------------------------------------------------
; General Register Usage:
;---------------------------------------------------------------------------
; d0 ----SCRATCH----
; d1 ----SCRATCH----
; d2 ----SCRATCH----
; d3 SCC write base offset
; d4.hw set by *B command
; d4.lw timer counter
; d5.hw command byte (for echo)
; d5.lw ----SCRATCH----
; d6 minor error
; d7 major error/flags
;
; a0 set by *0 command
; a1 set by *1 command
; a2 VIA1 base address
; a3 SCC read base
; a4 set by *L command (load address), saves return address for PRAM rtns
; a5 Saves return address (for BSR5/RTS5), used by cmd parser
; a6 Saves return address (for BSR6/RTS6)
; a7 sp, reserved!
;
;-----------------------------------------------------------------------------
TMRestart ; <19>
WITH DecoderInfo,hwCfgInfo ; <19>
lea -VTEntries*4(sp),sp ;For <20>010 CPUs, VBR goes above the stack <19><16>
movea.l sp,a1 ; <19><16><1.8>
BSR6 SetVectorTable ;Set up our exception table in RAM <16>
TMEntry0 ; <19>
clr.l d6 ;start with clean plate <19>
clr.l d7 ; <19>
TMEntry1 ; <19><1.9>
moveq.l #0,d2
BigBSR6 JGetHardwareInfo,a0 ; <35>
move.l VIA1Addr(a0),a2 ;get VIA1 base address
btst.l #(hwCbPwrMgr+16),d2 ;do we have a pmgr?
beq.s @noPmgr ;branch if not
move.l a0,d0 ; do I need to save a0?
BigBSR6 USTPmgrTurnOn,a0 ;turn on a bunch of things
move.l d0,a0 ; restore a0
@noPmgr
@checkForASC
btst #test,d7 ;are we in board burn in?
bne.s @SkipSound ;yes, then skip the noise
moveq.l #0,d2 ;know something about machine already
BigBSR6 JGetHardwareInfo,a0 ; <35>
btst.l #ASCExists,d0 ;do we have a sound chip?
beq.s @SkipSound
move.l ASCAddr(a0),A3 ;get sound chip addr [2.6>[2.7>
movea.l VIA1Addr(a0),a5 ;setup VIA1 address for Beep <1.3>
BigBSR6 ErrorBeep4,a0 ;the fourth choice of several squawks...
@SkipSound
clr.l d5 ;clear command register
BSR6 SetupBases ;Get VIA1,SCC base addresses in a2,a3,d3
BSR6 InitSCC
getCmd BSR6 GetChar ;look at SCC/KBD for any input
tst.w d0 ;test char, neg word means no input
bmi Continue ;if negative then didn't get a char <SM8>
@gotChar
and.b #$7f,d0 ;mask character
cmpi.b #'*',d0 ;is it a star?
bne.s @checkCmd ;no, see if command char <36>
bset #star,d7 ;yes, flag that we've seen it
bra Continue
@checkCmd ;we got some other character <36>
btst #star,d7 ;have we already seen a star first? <36>
bne.s @gotStar ;yes, it must be a normal STM cmd <36>
cmpi.b #UTEChar,d0 ;Else, is this the UTE command char? <36>
bne Invalid ;just echo it if not <36>
bsr UTECmd ;else, go do it (we don't know if we're inited) <36>
move.l d0,-(sp) ;save the return status
BSR6 SetupBases ;After doing a CTE thing, we need to reinit
BSR6 InitSCC ;reinit scc if needed
move.l (sp)+,d0 ;restore the return status
tst.l d0 ;is everything OK?
bne CTEReturn ;echo what you have if not
move.b #UTEChar,d0 ;else, echo the UTE character to say we're done
bra CTEReturn ;Jump to invalid to send prompt
@gotStar ; <36>
bclr #star,d7 ;yes, we have a command byte...
moveq #0,d1 ;clear command offset reg
moveq #0,d2 ;clear byte counter
lea CmdTable,a5 ;point to our command table
@loop move.w (a5)+,d2 ;get count/command byte
beq Invalid ;exit if end of table
cmp.b d2,d0 ;is this our command?
beq.s @found ;yes, process it
adda.l #2,a5 ;no, skip over routine offset
bra.s @loop ;and try next
@found move.l a5,d5 ;save table entry pointer
lsr.w #8,d2 ;get byte cnt in lower byte
BSR6 GetNBytes ;Get up to 4 bytes in D1
move.l d5,a5 ;restore table entry pointer
move.b -1(a5),d5 ;re-fetch command byte
swap d5 ;keep in high byte of d5
move.w (a5),d0 ;get routine offset
@jump jmp (a5,d0.w) ;and jump to our routine
EJECT
;-----------------------------------------------------------------------------------
; Command Table Entries are long words of the form:
; Routine Offset (Word)
; Chars to get (Byte)
; Cmd Character (Byte)
;-----------------------------------------------------------------------------------
ALIGN 2
CmdTable
DC.B 0,'S'
DC.W Service-*
DC.B 4,'L'
DC.W LoadAddr-*
DC.B 2,'B'
DC.W ByteCnt-*
DC.B 0,'D'
DC.W GetData-*
DC.B 0,'C'
DC.W CheckSum-*
DC.B 4,'G'
DC.W Execute-*
DC.B 4,'0'
DC.W LoadA0-*
DC.B 4,'1'
DC.W LoadA1-*
DC.B 4,'2'
DC.W SetCache-*
DC.B 0,'3'
DC.W MMUOff-*
DC.B 0,'4'
DC.W ClearResult-*
DC.B 0,'5'
DC.W StartBootMsg-*
DC.B 0,'6'
DC.W CPUReset-*
DC.B 0,'7'
DC.W PreventSleep-*
DC.B 0,'A'
DC.W ASCIIMode-*
DC.B 0,'H'
DC.W HEXMode-*
DC.B 0,'R'
DC.W SendResults-*
DC.B 0,'M'
DC.W MemDump-*
DC.B 0,'E'
DC.W EchoOn-*
DC.B 0,'I'
DC.W InitTestManager-*
DC.B 2,'P'
DC.W PwrMgrCmd-*
DC.B 4,'T'
DC.W DoCritTest-*
DC.B 4,'N'
DC.W DoNonCritTest-*
DC.B 0,'V' ;Version command <23>
DC.W EchoVersion-* ; <23>
DC.B 0,'Z' ;Exit to the nub manager <32>
DC.W NubSTMDispatch-* ;Dispatch directly to the NUB <32>
DC.L 0
EJECT
EchoCmd
move.b #'*',d0 ;echo an asterisk
BSR6 OutChar ;
swap d5 ;get upper word
move.b d5,d0 ;get copy of received character
swap d5 ;restore d5
CTEReturn
BSR6 OutChar ;echo received char <v2.5>
bset #crlf,d7 ;send crlf <v2.5>
moveq #0,d2 ;no command <v2.5>
BSR6 PutNBytes ;send the crlf <v2.5>
bclr #crlf,d7 ;no more crlf <v2.5>
bra.s Continue ;skip invalid char processing <v2.5>
Invalid
BSR6 OutChar ;echo received char
Continue
btst #MsgQ,d7 ;any message queued to go out?
beq @NoUnQ
; Message queued up for output, see if timer active
btst #timer,d7 ;see if timer bit set
beq.s @NoTimer ;no, continue with message
; The timer is active so see if its expired yet
btst #5,VIFR(a2) ;see if counted out
beq @NoUnQ ;no, continue on
move.b #$20,VIER(a2) ;disable timer 2 interrupts
move.b #$FF,vT2C(a2) ;low byte
move.b #$FF,vT2CH(a2) ;high byte
subq.w #1,d4 ;count a timer expiration event
bpl @NoUnQ ;still counting...
move.w #sec,d4 ;expired, re-init d4.w
@NoTimer
lea a1Msg,a1 ;
BSR6 SendString
; d6.l/d7.w have the result codes to embed in the text stream
bclr.l #crlf,d7 ;no <cr-lf>
bset.l #aski,d7 ;send as ascii characters
move.l d6,d0 ;send d6.l result code register
moveq.l #4,d2 ;send 4 bytes
BSR6 PutNBytes ;send um
move.w d7,d0 ;send d7.w result code register
moveq.l #2,d2 ;send 2 bytes
BSR6 PutNBytes ;send um
bclr.l #aski,d7 ;revert to hex mode
; follow it up with the trailor msg that identifies the system
move.b #'*',d0
BSR6 OutChar ;output *
BSR6 SetupBases ;reinit the bases (also gets box flag in d2)
lea b1Msg,a1 ;point to our table <1.5>
lsr.w #8,d2 ;get boxflag <1.5>
ext.w d2 ;sign extend for neg offset if needed <1.5>
move.b (a1,d2.w),d0 ;get digit for this machine <1.5>
BSR6 OutChar ;send send it <1.5>
lea trailer,a1 ;point to *crlf
BSR6 SendString ;send it
btst #timer,d7 ;if timer is active then
bne.s @NoUnQ ; don't un-queue message
bclr #MsgQ,d7 ;not active so un-queue message
@NoUnQ bra getCmd ;keep looping....
EJECT
;================================================================================
; Test Manager Commands
;================================================================================
;-------------------------------------------------------------------------------
; *S Service mode request, turn off timer and queue flags.
;
; Inputs: none
; Outputs: none
; Destorys: none
;-------------------------------------------------------------------------------
Service
bclr #MsgQ,d7 ;clear any queued message
bclr #timer,d7 ;clear any timer active bit
lea EchoCmd,a6 ;load return address
jmp PutNBytes ;send result register
;-------------------------------------------------------------------------------
; *L Load Address. Setup our load address register (a4)
;
; Inputs: d1 - address received from serial port
;
; Outputs: a4 - load address
;-------------------------------------------------------------------------------
LoadAddr
move.l d1,a4 ;a4 now has load address
swap d4 ; <v2.5>
clr.w d4 ;initialize byte count to default <v2.5>
swap d4 ; <v2.5>
btst #echo,d7 ;wants an echo today?
beq EchoCmd ;no
bclr #crlf,d7 ;no <cr-lf>
move.l d1,d0 ;copy of load address <v2.5>
moveq #4,d2 ;send 4 bytes
lea EchoCmd,a6 ;load return address
jmp PutNBytes ;send load address
;-------------------------------------------------------------------------------
; *B Set byte count
;
; Inputs: d1.w - [from serial port]
;
; Outputs: d4.hw - byte count received
;
; Destroys: d0,d2
;-------------------------------------------------------------------------------
ByteCnt
swap d4
move.w d1,d4 ;save byte count in d4.hw
swap d4
btst #echo,d7 ;wants an echo today?
beq EchoCmd ;no
bclr #crlf,d7 ;no <cr-lf>
move.w d1,d0 ;copy of byte count
moveq #2,d2 ;send 2 bytes
lea EchoCmd,a6 ;load return address
jmp PutNBytes ;send byte count
;-------------------------------------------------------------------------------
; *D Data. Get data coming... generate checksum in d6,
; store data off a4 for d4.hw bytes
;
; Inputs: a4 - start address to checksum
; d4.hw - number of bytes to checksum
;
; Outputs: d6.l - checksum
;
; Destroys: d0,d1,d2,d4.hw,a4,a5
;-------------------------------------------------------------------------------
GetData
clr.l d6 ;clear for checksum calculation
swap d4
sub.w #1,d4 ;adjust for dbra
blt.s @exit ;exit if no bytes to get
@fetch moveq #1,d2 ;get a byte
BSR6 GetNBytes ;check for input
move.b d1,(a4)+ ;stuff into appropriate place
clr.l d0
move.b d1,d0 ;character to sum
add.l d0,d6 ;add to sum
dbra d4,@fetch ;until done....
@exit swap d4
bra EchoCmd ;then send response
;-------------------------------------------------------------------------------
; *C Checksum. Calculate the checksum off a4 for d4.hw
; bytes, then send checksum to serial port
;
; Inputs: a4 - start address to checksum
; d4.hw - number of bytes to checksum
;
; Outputs: d6.l - checksum
;
; Destroys: d0,d1,d2,d4.hw,a4,a5
;-------------------------------------------------------------------------------
CheckSum
clr.l d6 ;clear for checksum calculation [v1.1>
swap d4
sub.w #1,d4 ;adjust for dbra [v1.1>
blt.s @noMore ;ok to continue [v1.1>
@sum move.b (a4)+,d1 ;get a byte [v1.1>
clr.l d0
move.b d1,d0 ;character to sum [v1.1>
add.l d0,d6 ;add to sum [v1.1>
dbra d4,@sum
@noMore swap d4
bclr #crlf,d7 ;no <cr-lf> [v1.1>
move.l d6,d0 ;copy of result register d6.l [v1.1>
moveq #4,d2 ;send 4 bytes [v1.1>
lea EchoCmd,a6 ;load return address [v1.1>
jmp PutNBytes ;send result register [v1.1>
;-------------------------------------------------------------------------------
; *G Go execute
;
; Inputs: d1 - Starting address
;
; Outputs: d5 - 00470000
;
; Destroys: d0,d2,a2,????
;-------------------------------------------------------------------------------
Execute
move.l d1,a2 ;get jump address
lea @1,a6 ; setup return address <SM5> rb
jmp (a2) ;jump to downloaded code <SM5> rb
@1 ; <SM5> rb
BSR6 SetupBases ;restore VIA1,SCC registers
move.l #$00470000,d5
bra EchoCmd ;back to command parser
;-------------------------------------------------------------------------------
; *0 Set register A0. Load next 4 bytes into register a0
;
; Inputs: d1 - 4 bytes to load in a0
;
; Outputs: a0 - set to d1
;
; Destroys: d0,d1,d2,a5
;-------------------------------------------------------------------------------
LoadA0
move.l d1,a0 ;copy to a0
btst #echo,d7 ;wants an echo today?
beq EchoCmd ;no
bclr #crlf,d7 ;no <cr-lf>
move.l d1,d0 ;copy of received data
moveq #4,d2 ;send 4 bytes
lea EchoCmd,a6 ;load return address
jmp PutNBytes ;send received data
;-------------------------------------------------------------------------------
; *1 Set register A1. Load next 4 bytes into register a1
;
; Inputs: d1 - 4 bytes to load in a1
;
; Outputs: a1 - set to d1
;
; Destroys: d0,d1,d2,d3,a5
;-------------------------------------------------------------------------------
LoadA1
move.l d1,a1 ;copy to a1
btst #echo,d7 ;wants an echo today?
beq EchoCmd ;no
bclr #crlf,d7 ;no <cr-lf>
move.l d1,d0 ;copy of received data
moveq #4,d2 ;send 4 bytes
lea EchoCmd,a6 ;load return address
jmp PutNBytes ;send received data
;-------------------------------------------------------------------------------
; *2 Set cache control register
;
; Inputs: d1 - 4 bytes to load in CACR
;
; Outputs: CACR set to 4 byte input
;
; Destroys: d0
;-------------------------------------------------------------------------------
SetCache
movec d1,CACR ;if heading to test manager
bra EchoCmd ;and echo
;-------------------------------------------------------------------------------
; *3 Turn off MMU translation
; and disable the data cache so I/O area will not be cached.
;
; Note: The data cache is only turned off in the 68030 case
; the 68040 case may need this done also. <SM9><TJR>
;
; Inputs: none
;
; Outputs: MMU turned off
;
; Destroys: d0, d1, a0
;-------------------------------------------------------------------------------
MMUDis dc.l 0 ;Disable MMU translation <20>
MMUOff
; Even tho the -IF- says "<22> 030", this means that we might have an 020 <30>
; because the Mac32 build will work for 020s as well, and is assembled with <30>
; CPU = 030. So we need to check whether or not we're an 020/030/040 <30>
movec cacr,d0 ;Test to see what kind of CPU we're on <20><30>
move.l d0,d1 ;Save the contents of the cacr register <20>
bset.l #31,d0 ; set CACR[DE] to test if on an 040 <30>
movec d0,CACR ; write it out <30>
movec CACR,d0 ; ... and see if it stuck <30>
btst.l #31,d0 ; are we on an 040? <30>
bne.s @onAn040 ; YES ... go disable 040 MMU <30>
; NO ... make sure we're not on an 020 <30>
bset.l #CAWA,d0 ;Set the Write allocate bit (020s don't have this) <20>
movec d0,cacr ;move it into the CACR <20>
movec cacr,d0 ;read it back <20>
btst.l #CAWA,d0 ;Are we an 030? (were we able to set WA?) <20>
beq.s @exit ;NO ... exit. CACR has not changed. <20>
lea MMUDis,a0 ;YES ... point to TC value that disables the MMU<20>
move.l #$00003819,d1 ;get ready to clear data and Inst. caches & disable data cache. <SM9><TJR>
movec d1,cacr ;do the cache stuff before turning off the MMU <SM9><TJR>
pmove (a0),tc ;turn off 030 MMU <20>
bra.s @exit ; ... then exit <30> <SM9><TJR>
@onAn040
; This is done this way to preserve the current setting for the pagesize bit <30>
; Otherwise, it could be done with: <30>
; sub.l d0,d0 ; set all TC bits to zero <30>
; movec d0,TC ; disable MMU, pagesize set to 4K <30>
MACHINE MC68040 ; required for below instructions <3>
movec TC,d0 ; retrieve TC <3>
bclr #15,d0 ; TC[E] bit is bit 15 on 040s. <3>
movec d0,TC ; disable MMU <3>
MACHINE MC68030 ; return to previous MACHINE directive <3>
@restoreCACR ; <30>
movec d1,cacr ;restore the cacr <20>
@exit
bra EchoCmd ;command not implemented
;-------------------------------------------------------------------------------
; *4 Clear result registers
;
; Inputs: none
;
; Outputs: d6 - cleared
; d7.w - cleared
;
; Destroys: none
;-------------------------------------------------------------------------------
ClearResult
clr.w d7 ;clear error registers
clr.l d6 ;
bra EchoCmd ;and echo
;-------------------------------------------------------------------------------
; *5 Queue up boot msg for host
;
; The boot message for board burn in or service log on is built from
; a header, result codes, and a trailor that identifies the system.
;
; The normal non-failure type message looks like this:
;
; *APPLE*876543210000*1*<cr><lf>
;
; The 87654321 part is the minor error code. These are decoded as
; follows: $87654321 = good, no failure
; $xxxxxxxx = 32 bits failed bits mask for RAM, Bus tests
; $yyyyyyyz = z is 4 bit mask of chip that failed ROM checksum
;
; The 0000 part is the major code as the
; equates in this file indicate by ErrXXXX codes.
;
; [v1.3> (((
;
; Note that in cpus after laguna (Hcmac) the 0000 part will consist of two parts:
; The msb of the word will contain the exception error code indicated by the exception
; error code equates in this file, if an unexpected exception occurred while running a test.
; If no exception occurred, then this byte will be clear.
; The lsb of the word will still contain the major error code indicated by the lsb of
; the ErrXXXX equate.
;
; ))) [v1.3>
;
;
; The *1* part identifies the system as a Mac II (or family member)
; The *2* part identifies the system as a Mac SE
; The *3* part identifies the system as a Mac+
; The *4* part identifies the system as a vader (laser ntx) [v1.3>
; The *5* part identifies the system as a Luke (laser nt) [v1.3>
; The *6* part identifies the system as a Portable (HcMac) [v1.3>
; The *7* part identifies the system as a Mac IIci (HafMac) <v1.1>
; The *8* part identifies the system as a Mac IIfx (MvMac) <v1.2>
; The *9* part identifies the system as a Woodstock <v1.5>
; The *A* part identifies the system as a Atlantic <v2.2>
; The *B* part identifies the system as a XO <15>
; The *C* part identifies the system as a Ericson <15>
; The *D* part identifies the system as a Elsie <15>
; The *E* part identifies the system as a Eclipse <15>
; The *F* part identifies the system as a Kirin <15>
; The *G* part identifies the system as a Kirin Dry <15>
;
;---------------------------------------------------------------------------
;
; Inputs: none
;
; Outputs: d4.lw - set to delay count
; d7 - flags set
;
; Destroys: none
;-------------------------------------------------------------------------------
StartBootMsg
bset #timer,d7 ;timer is active
bset #MsgQ,d7 ;boot msg is queued
move.w #sec,d4 ;set extended timer count <v2.5>
bsr6 StartTimer ;and start the timer
lea EchoCmd,a6 ;command end processor
jmp SetupBases ;restore VIA1,SCC registers
;-------------------------------------------------------------------------------
; *6 CPU Reset
;
; Inputs: none
; Outputs: none
; Destroys: none
;-------------------------------------------------------------------------------
CPUReset
Reset ;issue reset instruction
bra EchoCmd ;and echo
;-------------------------------------------------------------------------------
; *7 Prevent lack of charger from causing sleep; note
; that doing this probably requires a charger to be
; hooked up temporarily in order to issue this
; command.
;
; Inputs: none
; Outputs: d7 - nosleep flag set
; Destroys: none
;-------------------------------------------------------------------------------
PreventSleep
bset #nosleep,d7 ;set sleep bit to prevent us from napping <v1.0>
bra EchoCmd ;and echo <v1.0>
;-------------------------------------------------------------------------------
; *A set ASCII mode
;
; Inputs: none
; Outputs: d7 - flag set
; Destroys: none
;-------------------------------------------------------------------------------
ASCIIMode
bset #aski,d7 ;set ascii mode bit
bra EchoCmd
;-------------------------------------------------------------------------------
; *H set HEX mode
;
; Inputs: none
; Outputs: d7 - flag cleared
; Destroys: none
;-------------------------------------------------------------------------------
HEXMode
bclr #aski,d7 ;clear ascii mode bit
bra EchoCmd
;-------------------------------------------------------------------------------
; *R send test results (4 bytes) to serial port
;
; Inputs: none
; Outputs: none
; Destroys: d0,d1,d2,a5
;-------------------------------------------------------------------------------
SendResults
bclr #crlf,d7 ;no <cr-lf>
move.l d6,d0 ;copy of result register d6.l
moveq #4,d2 ;send 4 bytes
BSR6 PutNBytes ;send result register
bclr #crlf,d7 ;no <cr-lf>
move.w d7,d0 ;copy of result register d7.w
moveq #2,d2 ;send 2 bytes
lea EchoCmd,a6 ;load return address
jmp PutNBytes ;send result register
;-------------------------------------------------------------------------------
; *M Memory dump. Dump memory from (a4) for (d3.w) bytes
;
; Inputs: a4 - starting address of dump
; d4.hw - number of bytes to dump
;
; Outputs: a4 - points past last byte dumped
;
; Destroys: d0,d1,d2,d4,a5
;-------------------------------------------------------------------------------
MemDump
swap d4 ;get byte cnt
subq.w #1,d4 ;and for dbra
bge.s @dump ;is it ok to continue? <v2.5>
clr.w d4 ;always dump at least one byte <v2.5>
@dump bset #crlf,d7 ;append <cr-lf>
@loop move.l (a4)+,d0 ;get 4 bytes to send
moveq #4,d2 ;send 4 bytes
BSR6 PutNBytes ;send um
dbra d4,@loop
@done swap d4
bra EchoCmd ;done
;-------------------------------------------------------------------------------
; *E set echo mode
;
; Inputs: none
; Outputs: d7 - flag set
; Destroys: none
;-------------------------------------------------------------------------------
EchoOn
bset #echo,d7 ;echo received parameters
bra EchoCmd
;-------------------------------------------------------------------------------
; *I Initilize (restart) the Test Manager
;-------------------------------------------------------------------------------
InitTestManager
BigJmp BaseOfRom+ROMHeader.ReStart,a0 ;jump to restart vector <24>
;-------------------------------------------------------------------------------
; *P Power Manager command (command.b,cnt.b)
;
; Inputs: d1 - command/byte cnt
; a2 - VIA1 base
;
; Outputs: d7 - flag set
;
; Destroys: d0,d1,d2,d3,a1,a4,a5
;-------------------------------------------------------------------------------
PwrMgrCmd
lea ErrorMsg,a1
lea EchoCmd,a6 ; [v1.1>
jmp SendString ;we can't process it [v1.1>
EJECT
;-------------------------------------------------------------------------------
; *T Test (test#,passes,options)
;
; Inputs: d1 - test#,passes
;
; Outputs: d5 - $00540000
;
; Destroys: a0-a6,d0-d4
;-------------------------------------------------------------------------------
DoCritTest
BigLea ElsieTMVectors,a5 ;First see if we are on an Elsie <16>
BigLea StartTest1,a4 ;Get the address of the start vector <16>
cmpa.l 4(a5),a4 ;Does this agree with where we are? <16>
beq.s @onElsie ;Continue if so <16>
BigLea TMVectors,a5 ;Otherwise, load the default TM vectors <16>
@onElsie ; <16>
movec a5,VBR ;VBR points to our exception table <16>
move.l d1,a4 ;save test#/passes
btst #echo,d7 ;Echo wanted?
beq.s @getOpt ;no
move.l d1,d0
moveq #4,d2
BSR6 PutNBytes ;---echo test#/passes
@getOpt moveq #2,d2
BSR6 GetNBytes ;now get the options word
moveq.l #-1,d0 ;Create a mask for the option field in d7 <16>
move.l #stop,d2 ;Get lsb of options field <16>
lsl.l d2,d0 ;create our mask <16>
not.l d0 ;Invert it <16>
and.l d0,d7 ;and clear the options field <16>
move.w d1,d0 ;save a copy in case echo needed
lsl.l d2,d1 ;align error option bits
or.l d1,d7 ;and plop them into flags register
btst #echo,d7 ;echo wanted?
beq.s @loop ;no
moveq #2,d2
BSR6 PutNBytes ;---echo options word
; Next get the test number back and case it out to run the test requested.
@Loop clr.l d6 ;clear results register d6.l
move.l a4,d1
swap d1 ;get test number requested
move.b #nak,d0 ;preset invalid number received
; cmp.w MaxTest,d1 ;is valid test number?
and.l #$0000ffff,d1 ;clear out options word for now <H10><SM4>
cmp.l MaxTest,d1 ;is valid test number? <H10><SM4>
bge Invalid ;invalid, echo ? as nak
; asl.w #1,d1 ;adjust for table access
asl.l #2,d1 ;adjust for table access <H10><SM4>
lea TJump,a5 ;point to test jump table
; Due to the relocation of this file to USTStartTest1.a, I had to make the references
; in the TJump table longs instead of words. Therefore I had to modify some access code:
; WARNING: This is probably going to break STM because d1 is holding two values (in
; high word and low word). CHECK THIS OUT AARON AARON
;<3B><><EFBFBD> move.w (a5,d1.w),d1 ;fetch test offset from table
;<3B><><EFBFBD> lea (a5,d1.w),a5 ;...
move.l (a5,d1.l),d1 ;fetch test offset from table
lea (a5,d1.l),a5 ;...
lea @1,a6 ; setup return address <SM5> rb
jmp (a5) ;go execute test <SM5> rb
@1 ; <SM5> rb
movea.l #aStack,a7 ;Reset stack pointer, in case it was destroyed <19>
move.l a0,d4 ;save regs in case looping
move.l a1,d5
BSR6 SetupBases ;Get VIA1,SCC base addresses in a2,a3,d3
move.l d4,a0 ;restore regs
move.l d5,a1
tst.l d6 ;any errors this test?
beq.s @Continue ;no
; Error on test, check for loop and stop on error options
lea ErrorMsg,a1
BSR6 SendString ;send error message to serial port <v1.0>
btst #loop,d7 ;wants to loop on error?
beq.s @NoLoop ;no
@ErrLoop
lea @ErrLoop,a6 ;yes, loop on test
jmp (a5) ;until the cows come home....
@NoLoop btst #stop,d7 ;wants to stop on error?
bne.s @Echo ;yes
@Continue
move.l a4,d1
subq.w #1,d1 ;count a pass
beq.s @echo ;done, clean up and exit
movea.l d1,a4 ;save pass cnt
BSR6 GetChar
tst.w d0
bmi.s @Loop ;continue testing
@Echo move.l #$00540000,d5 ;fake a "T" to echo
bra EchoCmd
EJECT
;-------------------------------------------------------------------------------
; *N Non-critical Test (test#,passes,options)
;
; Inputs: d1 - test#,passes
;
; Outputs: d5 - $004E0000
;
; Destroys: a0-a6,d0-d4
;
; Note: Several non-critical tests require that the VBR be setup in RAM, so they
; can patch the interrupt vectors.
;-------------------------------------------------------------------------------
DoNonCritTest
movea.l d1,a4 ;save test#/passes in a4
BigBSR6 SizeMemory,a0 ;Size memory and set up the stack <16>
movea.l (sp),a1 ;Put the vectors at the base of bank A <16>
movea.l (a1),a1 ; <16>
BSR6 SetVectorTable ;Set up our exception table in RAM <16>
BSR6 SetupBases ;Get VIA1,SCC base addresses in a2,a3,d3<16>
btst #echo,d7 ;Echo wanted?
beq.s @getOpt ;no
move.l a4,d0 ;Restore the test#/passes for echo <16>
moveq #4,d2
BSR6 PutNBytes ;---echo test#/passes
@getOpt moveq #2,d2
BSR6 GetNBytes ;now get the options word
moveq.l #-1,d0 ;Create a mask for the option field in d7 <16>
move.l #stop,d2 ;Get lsb of options field <16>
lsl.l d2,d0 ;create our mask <16>
not.l d0 ;Invert it <16>
and.l d0,d7 ;and clear the options field <16>
move.w d1,d0 ;save a copy in case echo needed
lsl.l d2,d1 ;align error option bits
or.l d1,d7 ;and plop them into flags register
btst #echo,d7 ;echo wanted?
beq.s @valid ;no
moveq #2,d2
BSR6 PutNBytes ;---echo options word
; Next get the test number back and case it out to run the test requested.
@valid
move.l a4,d1
swap d1 ;get test number requested <v1.0>
sub.w #$84,d1 ;subtract out non-crit offset <v1.1><SM9><HY>
; cmp.w MaxNTst,d1 ;is valid test number? <v1.0>
and.l #$0000ffff,d1 ; mask off test number <H10><SM4>
cmp.l MaxNTst,d1 ;is valid test number? <v1.0><H10><SM4>
blt @table ;yes, continue
move.b #nak,d0 ;preset invalid number received <v1.0>
bra Invalid ;invalid, echo ? as nak <v1.0>
;@table asl.w #1,d1 ;adjust for table access <v1.0>
@table asl.l #2,d1 ;adjust for table access <v1.0><H10><SM4>
lea NJump,a5 ;point to test jump table <v1.0>
; Due to the relocation of this file to USTStartTest1.a, I had to make the references
; in the NJump table longs instead of words. Therefore I had to modify some access code:
; WARNING: This is probably going to break STM because d1 is holding two values (in
; high word and low word). CHECK THIS OUT AARON AARON
;<3B><><EFBFBD> move.w 0(a5,d1.w),d1 ;fetch test offset from table <v1.0>
;<3B><><EFBFBD> lea 0(a5,d1.w),a5 ;... <v1.0>
move.l 0(a5,d1.l),d1 ;fetch test offset from table <v1.0>
lea 0(a5,d1.l),a5 ;... <v1.0>
move.w a4,-(sp) ;keep loopcount on stack <1.8>
move.l a5,-(sp) ;save on stack <1.8>
moveq.l #0,d2 ;d2 prep'd for universal call <1.8>
BigBSR6 JGetHardwareInfo,a0 ; <35>
move.l (sp)+,a5 ;save on stack <16><1.8>
movem.l d0-d2/a0-a2/a5,-(sp) ;save universal registers <16><1.8><7>
@Loop clr.l d6 ;clear results register d6.l
movem.l (sp),d0-d2/a0-a2/a5 ;setup universal regs <16><7>
lea @1,a6 ; setup return address <SM5> rb
jmp (a5) ;go execute test <SM5> rb
@1 ; <SM5> rb
BSR6 SetupBases ;Get VIA1,SCC base addresses in a2,a3,d3
BSR6 InitSCC ;reinit scc if needed <v1.0>
tst.l d6 ;any errors this test? <v1.0>
beq.s @Continue ;no <v1.0>
; Error on test, check for loop and stop on error options
lea ErrorMsg,a1 ;point to *Error* string
BSR6 SendString ;we can't process it [v1.1>
btst #loop,d7 ;wants to loop on error? <v1.0>
beq.s @NoLoop ;no <v1.0>
@ErrLoop
lea @ErrLoop,a6 ;yes, loop on test <v1.0>
movem.l (sp),d0-d2/a0-a2/a5 ;restore regs <16><1.8><7>
jmp (a5) ;until the cows come home.... <v1.0>
@NoLoop btst #stop,d7 ;wants to stop on error? <v1.0>
bne.s @Echo ;yes <v1.0>
@Continue
subq.w #1,28(sp) ;count a pass <7>
beq.s @echo ;done, clean up and exit
BSR6 GetChar ; <v1.0>
tst.w d0 ; <v1.0>
bmi @Loop ;continue testing <v1.0>
@Echo lea 30(sp),sp ;dump saved registers off stack <16><1.8><7>
move.l #$004E0000,d5 ;fake a "N" to echo <v1.0>
bra EchoCmd
;------------------------------------------------------------------------------- <23>
; *V Echo version number <23>
; <23>
; Inputs: none <23>
; <23>
; Outputs: Echos the current serial test manager version number <23>
; <23>
; Destroys: a0-a3,a5,d0,d2,d3 <23>
; <23>
;------------------------------------------------------------------------------- <23>
EchoVersion ; <23>
BSR6 SetupBases ;Restore our state, in case we're lost <23>
BSR6 InitSCC ;reinit scc if needed <23>
lea Version,a1 ;Get a pointer to the version string <23>
BSR6 SendString ;print error msg <23>
move.l d7,d4 ;Preserve d7 <25>
bset.l #aski,d7 ;Set to ASCII mode <25>
bclr.l #crlf,d7 ;clear the CRLF option <25>
BigLea BaseOfRom+ROMHeader.ROMVersion,a0 ;Get address of ROM ver # <25>
move.b (a0),d0 ;Get the version # <25>
moveq.l #1,d2 ;get # bytes to write <25>
BSR6 PutNBytes ;write out this information <25>
move.b #' ',d0 ;put out a space seperator
BSR6 OutChar ;
Biglea BaseOfRom+ROMHeader.ROMRelease,a0 ;Get address of release # <25>
move.w (a0),d0 ;put release # in place <25>
moveq.l #2,d2 ;# bytes to write <25>
bset.l #crlf,d7 ;set the CRLF option <25>
BSR6 PutNBytes ;Write out this information <25>
move.l d4,d7 ;restore d7 <25>
bra EchoCmd ;Echo command and finish <23>
;------------------------------------------------------------------------------- <32>
; *Z Dispatch to the nub manager <32>
; <32>
; Inputs: none <32>
; <32>
; This entry point simply jumps to the nub manager. This is a one way street, <32>
; i.e., once you go to the nub manager, you can't come back! <32>
; <32>
;------------------------------------------------------------------------------- <32>
; This is a jump to self for now - nub entry point to be added later <32>
NubTMEntry
NubSTMDispatch BigJmp NubTMEntry,a0 ;Jump to the nub <32>
; This is a jump to self for now - nub entry point to be added later <32>
NubMgrTrap
NubMgrDispatch BigJmp NubMgrTrap,a0 ;Jump to the nub <32>
EJECT
;---------------------------------------------------------------------------
; Routine sets up the VIA1 and SCC base addresses in registers, for use
; throughout the Test Manager.
;
; Called by BSR6
;
; Inputs:
;
; Outputs: a2 - VIA1 base address
; a3 - SCC read base address
; d3 - SCC write base offset
;
; Destroys: a0-a3,a5,d0-d3
;---------------------------------------------------------------------------
SetupBases
WITH DecoderInfo
move.l a6,d3 ;save return address <H12><SM6>
moveq.l #0,d2
BigBSR6 JGetHardwareInfo,a0
move.l d3,a6 ;restore return address <H12><SM6>
move.l VIA1Addr(a0),a2 ;get VIA1 base address
btst.l #SCCIOPExists,d0 ;do we have an iop scc?
beq.s @noIOP
move.l SCCIOPAddr(a0),a3 ;get iop scc base address
moveq.l #0,d3 ;write base offset is 0
bra.s @exit
@noIOP move.l SCCRdAddr(a0),a3 ;get scc read base
move.l SCCWrAddr(a0),d3 ;get scc write base
sub.l a3,d3 ;calculate write reg offset
ENDWITH
@exit RTS6
;---------------------------------------------------------------------------
; Routine to initialize the SCC chip for I/O at 9600 baud async.
; Set the SCC inited bit status register D7 when done. This routine uses
; the table that follows.
;
; Called by BSR6
;
; Inputs: d0 - Bases valid flags
; a2 - VIA1 base address
; a3 - SCC base address
; d3 - SCC write base offset
;
; Outputs: d7 - flags set to indicate scc inited
;
; Destroys: d0-d2,a0,a1,a5
;
;---------------------------------------------------------------------------
InitSCC
movea.l a6,a5 ; Save caller's return address
@installed ; <v1.1>
btst.l #SCCIOPExists,d0 ;do we have an iop scc?
beq.s @sync ;no, init it
BigBSR6 SetSCCIOPBypass,a0 ;yes, throw SCC IOP into bypass mode <v1.1>
@sync tst.b 0(a3,d3.l) ;sync up accept address byte
lea PortSetUp,a1 ;point at set up table
@loop move.b (a1)+,d0 ;get SCC register to access
bmi.s @done ;done with init
move.b d0,Actl(a3,d3.l) ;select SCC register
move.b (a1)+,Actl(a3,d3.l) ;write data to SCC register
bra.s @loop ;until done...
@done bset #SCCok,d7 ;set SCC inited status bit
move.b aData(a3),d0 ;
bset.b #sync,vDirA(a2) ;set the sync bit as an output <38>
move.b vBufA(a2),d0 ;get current output register A
bclr #sync,d0 ;clear the sync bit
move.b d0,vBufA(a2) ;write ORA with overlay off
jmp (a5) ;then exit
;-----------------------------------------------------------------------------------
; Serial port A set up table, for 9600 baud async. The calculation for baud
; rate constant is:
;
; BR constant = [Clock Rate/(32*BaudRate)] - 2
;
; This translates to (NuMacConst/BaudRate) - 2 = 115200/9600 - 2 = about $000A
;
; or (MacConst/BaudRate) - 2 = 114709/9600 - 2 = about $000A
;
; For BaudRate of 19200: = 11709/19200 - 2 = about $0004
;-----------------------------------------------------------------------------------
PortSetUp
dc.b $09,$C0 ;reg 9, reset hardware
dc.b $0F,$00 ;reg 15, disable interrupts
dc.b $04,$4C ;reg 4, X16clk,8 bit,2 stop
dc.b $0B,$50 ;reg 11, rClk = tClk = BR gen
dc.b $0E,$00 ;reg 14, disable BR gen
; dc.b $0D,$00 ;reg 13, high byte 9600 baud
; dc.b $0C,$0A ;reg 12, low byte 9600 baud
dc.b $0C,$04 ;reg 12, low byte 9600 baud
dc.b $0D,$00 ;reg 13, high byte 9600 baud
dc.b $0E,$01 ;reg 14, enable BR gen
dc.b $0A,$00 ;reg 10, NRZ
dc.b $03,$C1 ;reg 3, Rx 8 bits, enabled
dc.b $05,$EA ;reg 5, Tx 8 bits, DTR/RTS
dc.b $01,$00 ;reg 1, Ext Sts interrupts disabled
dc.b $FF,$FF ;end of table
;---------------------------------------------------------------------------
; Routine to send out a character on SCC port A. Note that is routine will
; hang waiting for TXBE status since there is no timeout.
;
; Called by BSR6
;
; Inputs: d0.b - character to send
; a3 - SCC base address
; d3 - SCC write base offset
; Outputs: none
;
; Destroys: d0
;---------------------------------------------------------------------------
OutChar
move.b #$30,Actl(a3,d3.l) ;reset any errors
move.b d0,Adata(a3,d3.l) ;send character
@wait move.w #1,d0 ;wait until all sent status
move.b d0,Actl(a3,d3.l) ;select RR1
btst #0,Actl(a3) ;All Sent?
beq.s @wait
RTS6 ;exit
EJECT
;---------------------------------------------------------------------------
; This routine sends the message pointed to by a1 to the serial port.
; The string should be terminated by a null.
;
; Called by BSR6
;
; Inputs: d3 - SCC write base offset
; a1 - ptr to zero terminated string
; a3 - SCC read base
; a6 - return address
; Outputs: none
;
; Destroys: d0,d1,a0,a1
;---------------------------------------------------------------------------
SendString
movea.l a6,a0 ;save return address [v1.1> <v1.0>
@loop move.b (a1)+,d0 ; [v1.1>
beq.s @done
BSR6 OutChar ;
bra.s @loop ;
@done jmp (a0) ; [v1.1> <v1.0>
;---------------------------------------------------------------------------
; note: the following identifiers are reserved for use on LaserWriter <15>
; products and must not be used by CPU products: 4,5,9,F,G <15>
;---------------------------------------------------------------------------
ErrorMsg dc.b '*ERROR*',0 ;error message
a1Msg dc.b '*APPLE*',0 ;header message
dc.b '0' ;$FD boxflag = unknown trailor message
dc.b '3' ;$FE boxflag = MacPlus trailor message
dc.b '2' ;$FF boxflag = MacSE trailor message
b1Msg dc.b '1' ; 0 boxflag = Mac II trailor message
dc.b '1' ; 1 boxflag = Mac IIx trailor message
dc.b '1' ; 2 boxflag = Mac IIcx trailor message
dc.b '1' ; 3 boxflag = Mac SE30 trailor message
dc.b '6' ; 4 boxflag = Esprit trailor message
dc.b '7' ; 5 boxflag = Aurora25 trailor message
dc.b '8' ; 6 boxflag = 4Sq trailor message
dc.b '8' ; 7 boxflag = F19 trailor message
dc.b 'A' ; 8 - Aurora 16MHz 3 slot package <2.2>
dc.b 'A' ; 9 - Aurora 25MHz SE30 package (reserved for future) <12>
dc.b 'A' ;10 - Aurora 16MHz SE30 package (reserved for future) <12>
dc.b 'B' ;11 - XO (SE with 1 int floppy, brightness PWM) <12>
dc.b 'C' ;12 - Macintosh IIsi (20MHz, 030, optl 68882, MDU, RBV,1 direct slot) <12>
dc.b 'D' ;13 - Macintosh LC (16 MHz, 020, 1 direct slot) <12>
dc.b 'E' ;14 - Eclipse (040, 5 slots+PDS, VIA1&2, Orwell MCA, 2 IOPs, SCSI DMA) <12>
dc.b 'H' ;15 - Tim (16/25 MHz, 030, optional FPU, VIA1&2, JAWS, PMGR
dc.b 'I' ;16 - Spike (25MHz 040, 1 PDS, 2 NuBus, Orwell
dc.b 'J' ;17 - Apollo
dc.b 'K' ;18 - Asahi (Its a Sony!) Portable - PowerBook 100
dc.b 'L' ;19 - 16 Mhz Tim (TimLC - PowerBook 140)
dc.b 'M' ;20 - Zydeco (33 MHz Eclipse) - Quadra 950
dc.b 'N' ;21 - Vail (25 MHz, 030, optional FPU, 1 PDS, Sonora)
dc.b 'O' ;22 - Carnation (33 MHz, 030, FPU, 1 direct NuBus-capable slot, 3 NuBus slots)
dc.b 'P' ;23 - DBLite (Dark Becks, in case you were wondering)
dc.b 'Q' ;24 - Wombat (25MHz 040 or 040LC, 3 slots+PDS, VIA1&2, djMEMC, SCSI 53c96, optional enet) <H9><SM6>
dc.b 'R' ;25 - Columbia (25 Mhz, 030, PDS, Atlantis Decoder, Color Classic) <SM6>
dc.b 'S' ;26 - 33MHz DBLite (030, PMGR, expansion connector, no floppy) <H9><SM6>
dc.b 'T' ;27 - Dartanian (33Mhz, 030, FPU, VIA1&2, Niagra, PMGR, 1 direct slot) <SM6>
dc.b 'U' ;28 - DartanianLC <H7><SM6>
dc.b 'V' ;29 - Wombat (33MHz 040, 3 slots+PDS, VIA1&2, djMEMC, SCSI 53c96,enet, Frigidaire plastics) <H9><SM6>
dc.b 'W' ;30 - Wombat (33Mhz 040, 3 slots+PDS, VIA1&2, djMEMC, SCSI53c96, enet, Lego plastics) <H9><SM6>
dc.b 'X' ;31 - Foster Farms (68030 LC) <H9><SM6>
dc.b 'Y' ;32 - 16MHz DBLite (030, PMGR, expansion connector, no floppy) <H9><SM6>
dc.b 'Z' ;33 - 20MHz DBLite (030, PMGR, expansion connector, no floppy) <H9><SM6>
dc.b 'a' ;34 - Vail (16 MHz, 030, optional FPU, 1 PDS, Sonora) <H9><SM6>
dc.b 'b' ;35 - Carnation (25 MHz, 030, FPU, 3 NuBus slots) <H9><SM6>
dc.b 'c' ;36 - Carnation (16 MHz, 030, FPU, 3 NuBus slots) <H9><SM6>
dc.b 'd' ;37 - Cyclone <H9><SM6>
dc.b 'e' ;38 - Brazil (16Mhz, Lego package) <H9><SM6>
dc.b 'f' ;39 - Brazil (32MHz on motherboard, Lego package) <H9><SM6>
dc.b 'g' ;40 - Brazil (16MHz, Fridgidaire minitower package) <H9><SM6>
dc.b 'h' ;41 - Brazil (32MHz on motherboard, Fridgidaire package) <H9><SM6>
dc.b 'i' ;42 - Brazil (any speed, any package for consumer release) <H9><SM6>
dc.b 'j' ;43 - Slice <H9><SM6>
dc.b 'k' ;44 - Monet (33MHz 030/FPU, VIA1&2, Niagara, PMGR, 16 color LCD, 1 direct slot) <H9><SM6>
dc.b 'l' ;45 - Wombat (40MHz 040, 3 slots+PDS, VIA1&2, djMEMC, SCSI 53c96, enet) <H9><SM6>
dc.b 'm' ;46 - WLCD (20 MHz 040LC, PDS only, VIA1&2, djMEMC, SCSI 53c96, optional enet) <H9><SM6>
dc.b 'n' ;47 - WLCD (25 MHz 040LC, PDS only, VIA1&2, djMEMC, SCSI 53c96, optional enet) <H9><SM6>
dc.b 'o' ;48 - PowerBook 145 (25MHz 030, no FPU, otherwise same as 140) <H9><SM6>
trailer dc.b '*',$0D,$0A,00 ;*crlf
Version dc.b 'STM Version 2.2, Aaron Ludtke ',$0D,$0A ;STM version number <38>
dc.b 'CTE Version 2.1 ',$0D,$0A ;CTE version number <38>
dc.b 'ROM Version ' ;ROM version number goes next <38>
dc.b 0 ;terminator
align
EJECT
;---------------------------------------------------------------------------
; Start VIA 1 timer 2.
;
; Called by BSR6
;
; Inputs: a2 - VIA1 base address
; a6 - return address
; Outputs: none
; Destroys: d0-d2,a0-a5
;---------------------------------------------------------------------------
StartTimer
move.l a6,a3 ;save away in a3 (only safe place!) <v2.5>
moveq.l #0,d2 ;prepare for universal call
BigBSR6 JGetHardwareInfo,a0 ; <35>
move.l VIA1Addr(a0),a2 ;point to VIA 1 base <v2.5>
move.b #$00,VACR(a2) ;set up timer 2 for timed interrupts
move.b #$20,VIER(a2) ;disable timer 2 interrupts
move.b #$FF,vT2C(a2) ;low byte
move.b #$FF,vT2CH(a2) ;high byte
jmp (a3)
;---------------------------------------------------------------------------
; Check VIA 1, timer 2 count and if expired, restart, then decrement
; d4.lw. If d4.lw counted < 0, then d0 is set < 0 for caller to
; indicate timer has expired.
;
; Called by BSR6
;
; Inputs: d0.w - d4 init value, if timer expires
; d4.lw - interrupt counter
; a2 - VIA1 base address
; a6 - return address
;
; Outputs: d0.w - sign bit set if we timed out
; d4.lw - decremented, set to d0.w if expired
;
; Destroys: d1-d2,a0-a1,a5
;---------------------------------------------------------------------------
CheckTimer
move.l a6,a5 ;save return address
bclr #15,d0 ;say timer not expired
btst #5,VIFR(a2) ;see if counted out
beq.s @exit ;no, continue on
move.b #$20,VIER(a2) ;disable timer 2 interrupts
move.b #$FF,vT2C(a2) ;low byte
move.b #$FF,vT2CH(a2) ;high byte
subq.w #1,d4 ;count a timer expiration event
bpl.s @exit ;still counting...
move.w d0,d4 ;expired, re-init d4.w
bset #15,d0 ;flag expired with d0.w < 0
@exit jmp (a5) ;and exit
;---------------------------------------------------------------------------
; Routine to check SCC for any available input. <v1.0>
;
; Called by BSR6
;
; Inputs: a3 - SCC read base
; d3 - SCC write base offset
;
; Outputs: d0.w - Character received. Bit 15 set if SCC not
; inited or no character in rcv buffer
;
; Destroys: none
;---------------------------------------------------------------------------
GetChar
move.w #$8000,d0 ;say no input
btst #SCCok,d7 ;SCC inited?
beq.s @exit ;no, exit this place with no input <v1.0>
btst #rxbf,Actl(a3) ;any char avail at port A?
beq.s @exit ;exit no char avail
moveq #1,d0 ;address register 1 for errors
move.b d0,Actl(a3,d3.l) ;select reg 1
move.b Actl(a3),d0 ;get error flags byte
and.b #$70,d0 ;mask off non-error bits
beq.s @CharWaiting ;no errors, skip error reset
move.b #$30,Actl(a3,d3.l) ;reset errors
@CharWaiting
lsl.l #8,d0 ;shift flags to upper byte
move.b Adata(a3),d0 ;read data byte
@exit RTS6 ;got input char, exit to caller
;---------------------------------------------------------------------------
; Routine to convert from hex ascii to hex. If the character to convert is
; not in the range $30 - $39 or $41 - $46 then hex $00 is returned for
; the converted value.
;
; Called by BSR6
;
; Inputs: d0.b - ascii character ['0'-'9','A'-'F']
; Outputs: d0.b - converted nibble [0-15]
;
; Destroys: none
;---------------------------------------------------------------------------
;
CvtAscii
and.w #$007F,d0 ;clear any other debris
sub.b #$30,d0 ;remove ascii bits
bmi.s @error ;below min bound, exit with $00 code
cmp.b #$16,d0 ;is above max bound?
bgt.s @error ;yes, exit with $00 code
cmp.b #9,d0 ;is a letter code?
ble.s @numeric ;
sub.b #7,d0 ;remove letter part
@numeric
RTS6 ;exit
@error clr.w d0 ;code $00
RTS6 ;exit
;---------------------------------------------------------------------------
; Get the next N input bytes into register d1, where N is in d2.
;
; Inputs: d2.w - number of bytes to get [0..4]
; d3 - SCC write base offset
; a3 - SCC read base offset
;
; Outputs: d1 - bytes [1..4]
;
; Destroys: d0,d2,a5
;---------------------------------------------------------------------------
GetNBytes
move.l a6,a5 ;copy return address
tst.w d2 ;any bytes to get?
beq.s @exit ;no, exit
clr.l d1 ;clear dest reg
btst #aski,d7 ;doing hex or ascii?
beq.s @adjust ;hex
asl.w #1,d2 ;ascii, double byte count
@adjust subq.w #1,d2 ;adjust for dbra
@loop BSR6 GetChar ;check for input
tst.w d0
bmi.s @loop ;wait for char
btst #aski,d7 ;hex or ascii?
beq.s @hex ;hex
BSR6 CvtAscii ;converted to hex nibble $0-$F
lsl.l #4,d1 ;make room for another nibble
or.b d0,d1 ;or in the nibble, bits 8-15 = 0
bra.s @next
@hex lsl.l #8,d1
move.b d0,d1 ;move byte xx to result register
@next dbra d2,@loop
@exit jmp (a5)
;---------------------------------------------------------------------------
; Routine to convert from hex ascii to hex. If the character to convert is
; not in the range $30 - $39 or $41 - $46 then hex $00 is returned for
; the converted value.
;
; Called by BSR6
;
; Inputs: d0.b - nibble to convert [0-15]
; Outputs: d0.b - converted ascii char ['0'-'9','A'-'F']
;
; Destroys: none
;---------------------------------------------------------------------------
;
CvtHex
cmp.b #10,d0 ;needs number or letter?
blt.s @num
add.b #7,d0 ;offset for letters
@num add.b #$30,d0 ;make ascii character
RTS6 ;exit
;---------------------------------------------------------------------------
; Routine to output N bytes from register d0, where N is passed in d2.
; If N = 0 then just send cr-lf if flag is true.
;
; Called by BSR6
;
; Inputs: d0.l - Bytes to send
; d2 - Number of bytes to send [0..4]
; d3 - SCC write base offset
; a3 - SCC read base address
; Outputs: none
;
; Destroys: a5,d0,d1,d2
;---------------------------------------------------------------------------
PutNBytes
move.l a6,a5 ;save return address
move.l d0,d1 ;copy bytes to send
tst.w d2 ;sending anything today?
beq.s @crlf ;maybe just cr-lf
moveq #4,d0 ;get a 4
sub.w d2,d0 ;4-n = number of places to shift up
mulu #8,d0 ;number of bits to shift left
rol.l d0,d1 ;align first byte to shift to msb
btst #aski,d7 ;doing hex or ascii?
beq.s @hex ;hex
asl.w #1,d2 ;ascii, double byte count
@hex subq.w #1,d2 ;adjust for dbra
@loop btst #aski,d7 ;doing hex or ascii?
bne.s @ascii ;ascii
rol.l #8,d1 ;hex, get the whole byte ready
move.b d1,d0 ;msb
bra.s @send ;and skip the ascii conversion
@ascii rol.l #4,d1 ;get first nibble
move.b d1,d0 ;get first byte
and.b #$0F,d0 ;...nibble at it
BSR6 CvtHex ;convert nibble to ASCII
@send BSR6 OutChar ;
dbra d2,@loop ;and repeat until done
@crlf btst #crlf,d7 ;wants a <cr-lf> appended?
beq.s @exit ;no
move.b #cr,d0 ;send <cr>
BSR6 OutChar
move.b #lf,d0 ;send <lf>
BSR6 OutChar
@exit jmp (a5) ;and exit
;---------------------------------------------------------------------------
TM_SendByte ; <11><8>
movea.l a6,a5 ; Save return address <11>
move.b d2,vSR(a2) ; Put data in VIA data reg <11>
bset.b #vViaFullBit,vBufB(a2) ; Assert VIA Full <11>
@10 btst.b #ifSR,vIFR(a2) ; Wait for IRQ <11>
beq.s @10 ; Poll until set <11>
tst.b vSR(a2) ; Clear IRQ <11>
bclr.b #vViaFullBit,vBufB(a2) ; De-assert VIA Full <11>
movea.l a5,a6 ; Have the next routine return to caller <11>
jmp TM_Wait ; Give Egret a breather <11><8>
;---------------------------------------------------------------------------
TM_GetByte ; <8>
movea.l a6,a5
bclr.b #vViaFullBit,vBufB(a2) ; De-assert VIA Full <11>
@10 btst.b #ifSR,vIFR(a2) ; Wait for IRQ
beq.s @10 ; Poll until set
bset.b #vViaFullBit,vBufB(a2) ; Assert VIA Full
move.b vSR(a2),d2 ; Read data from VIA (clears IRQ)
BSR6 TM_Wait ; Give Egret a breather <8>
and.w #$00FF,d2 ; isolate the byte
btst.b #vXcvrSesBit,vBufB(a2) ; Return with state of XCVR Session
jmp (a5) ; Return to caller
;---------------------------------------------------------------------------
TM_Wait move.w #delay325uS,d0 ;Delay using a VIA access as a time base <17>
@delay tst.b vBufB(a2) ;Touch the VIA (each access is ~127<32>S <17>
dbra.w d0,@delay ;Delay
RTS6
;---------------------------------------------------------------------------
dispose
movea.l a6,a4 ; save the return address
btst.b #vXcvrSesBit,vBufB(a2) ; Is XCVR Session asserted?
bne.s @20 ; if not, just delay and return
BSR6 TM_Wait ; Give Egret a breather <11><8>
bset.b #vSysSesbit,vBufB(a2) ; Else set Sys Session <11>
@10 BSR6 TM_GetByte ; Read a byte - to throw away <8>
beq.s @10 ; xcvr ses still on? (active low)
bclr.b #vSysSesbit,vBufB(a2) ; Turn off SYS Session
bclr.b #vViaFullBit,vBufB(a2) ; Then de-assert VIA Full <11>
@20 movea.l a4,a6 ; Have the next routine return to caller
jmp TM_Wait ; dispatch to wait 250<35>Secs <8>
;---------------------------------------------------------------------------
; This routine is a register-based version of the Power Mgr trap. It is
; used when we don't know the state of RAM but still need to access the
; Power mgr for some reason, i.e. store startTest results in parameter RAM.
; d0.w should contain the command byte and the number of data bytes to transfer.
; d1 contain the data to tranfer. Obviously, any command that requires over
; 4 data bytes can not be used. For those commands that require a receive
; buffer, data will be placed back into d0-d1, thus destroying the previous
; contents. In addition, a0.w will contain 0 if successful, error code if
; unsuccessful. This is as much of a direct port of the real Power manager
; as was possible. Data is read out of the xfer/rcv 'buffer' from msb to lsb
; of d1.
;
; Called by BSR6
;
; Inputs: d0.w - command byte/#bytes
; d1.l - up to 4 bytes to xfer/rcv
; a2 - VIA1 base address
;
; Outputs: a0 - 0 if successful, error code otherwise
;
; Destroys: a4-a5,d0-d2, d5
; Preserves: a1-a3, d3-d4
;---------------------------------------------------------------------------
quasiPwrMgr ; [v1.1>
move.l a6,a5 ;save return address
jmp (a5)
;---------------------------------------------------------------------------
; This routine calls the OS SizeMemory routine, and returns the pointer
; to the memory location table in register d6, with d7.b clear. If SizeMemory
; returned an error, the bad bit mask is left in d6, with d7.b=$FF.
;---------------------------------------------------------------------------
SizeMem ; <1.7><2.0>
move.l a6,usp ;save return address
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; WARNING! Check this out carefully...it seems to me that some of the diagnostic
; environments that jump through this SizeMem area rely on ALL of the registers
; to stay intact. If that's true, then I can't make a BigBSR6,a0 call to SizeMemory
; because it will wipe out a0. There is no memory available right now to save
; registers. TRIPLE CHECK THIS!!! AARON AARON
;
; The SizeMemoryPatch uses a0 to do a GetHardwareInfo call, so it's safe to trash
; a0 here. HAL 2/12/92
BigBSR6 SizeMemory,a0 ;make OS call
sne d7 ;d7=0 if good, d7=$FF if SizeMem failed
bne.s @exit ;errors, leave bit mask in d6...
move.l (sp),d6 ;return start of memory location table in d6
@exit
move.l usp,a6 ;retrieve return address
jmp (a6) ;go back home
SizeV8VRAMShell
;----------------------------------------------------------------------------- <35>
;
; This test sizes the Elsie V8 implementation of video RAM
; This is a very dangerous test! If video RAM is resized it will change the way
; address lines are multiplexed to the DRAMs from the V8 chip. This will result in
; system memory being scrambled.
;
; This test is OK to run from the serial test manager
;
; inputs:
; none
;
; output:
; d6.l -1 test does not apply (not on a V8 elsie
; 0 no video RAM installed (should have a latch SIMM
; 256K 256K of video RAM installed
; 512K 512K of video RAM installed
;
;----------------------------------------------------------------------------- <35>
movea.l a6,a3 ;save the return address <35>
moveq.l #0,d2 ;First set up the universal registers <35>
BigBSR6 JGetHardwareInfo,a0 ; <35>
moveq.l #0,a2 ;Make sure a2 is zero now <35>
BigBSR6 SizeV8VRAM,a4 ;and call the VRAM sizing routine <35>
move.l a2,d0 ;see what a2 is <35>
bne.s @applies ;if it's not zero, keep going <35>
moveq.l #-1,d6 ;otherwise, this test does not apply <35>
bra.s @done ;exit here <35>
@applies
moveq.l #0,d6 ;now zero d6 <35>
btst.b #V8vRAMIn,V8Exp(a2) ;is there any VRAM? <35>
beq.s @done ;nope, leave d6 set to zero <35>
move.l #1<<18,d6 ;else, report 256K of VRAM <35>
btst.b #V8512Row,V8Exp(a2) ;do we have 512K? <35>
bne.s @done ;exit if not <35>
lsl.l #1,d6 ;else, adjust d6 <35>
@done
jmp (a3) ;return (d6 contains the info) <35>
;<T5>
;-------------------------------------------------------------------------------
; Routine: SetVectorTable
;
; Inputs: a1 - where we want the table to be located
;
; Outputs: VBR - Points to RAM based exception table
;
; Destroys: a0-a2,d0-d2
;
; This routine sets up the exception vector table in RAM for any machine.
; A1 points to where we want the exception table. It makes the vectors point
; to the table in which we're presently running (ROM or RAM).
;-------------------------------------------------------------------------------
SetVectorTable
IF forRomulator THEN ; check if we are ReAnimator<6F>ing
TestInRAM a0 ; are we running in ram? <T9>
beq.s @Normal ; Change the VBR if we're not in RAM <T9>
movec vbr,a0 ;else, get the current vbr <T9>
move.w #VTEntries-1,d0 ;get the size of the vector table <T9>
movea.l a1,a2 ;save the new location <T9>
@CopyVBR
move.l (a0)+,(a1)+ ;copy a long <T9>
dbra.w d0,@CopyVBR ;copy it all <T9>
movec a2,vbr ; <T9>
RTS6 ; <T9>
@Normal
ENDIF ; {forRomulator}
BigLea BaseOfRom,a0 ;get actual base of rom address
move.l a0,d2
subi.l #RomStart,d2 ;subtract out equate
BigLea TMVectors,a0 ;point to ROM vector table
move.l a1,a2 ;keep copy of start of RAM vector table
move.w #VTEntries-1,d0 ;get number of entries
@loop move.l (a0)+,d1 ;get entry offset
add.l d2,d1 ;make it absolute
move.l d1,(a1)+ ;move into vector
dbra d0,@loop ;
movec a2,VBR ;VBR points to our exception table
RTS6 ;return
;------------------------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This marks the beginning of the "new" TestManager code.
;
;------------------------------------------------------------------------------
;
; If we get here we can assume that a0 points to the information that needs
; to be on the stack in order to make the selected call (the info has been setup by
; the "phony" GI_xxx calls in the file "app interface.a"). This entry point copies
; this information to the stack, then makes the call.
;
; In addition, d0 contains the TestManager function code as requested by the user. The
; function codes are divided up into two categories, with the delimiter being the value
; in the high word of d0. If the high word is 0001, then the request is for a CTE
; GI_xxx routine. If it is 0002, then it is a TM utility function. The codes are defined
; as follows:
;
; d0 = $xxx10000 GI_InitInterface
; $xxx10001 GI_GetVersion
; $xxx10002 GI_AllocPermMem
; $xxx10003 GI_AllocTempMem
; $xxx10004 GI_FreeTempMem
; $xxx10005 GI_GetCommentary
; $xxx10006 GI_GetDefaultExecutionOptions
; $xxx10007 GI_ExecuteDTM
;
; $xxx20000 Initialize the CTE interface for use with the TestManager
; $xxx20001 Get the info for a ROM-based test and subtest
;
; As it stands right now, there are entry points in the file "app interface.a"
; that setup the necessary info on the stack (with a0 pointing to it) and jump into
; the _TestManager entry point. There, the function code in d0 is checked, and if it
; is a "new" style TM call, it branches to here. Then, this routine takes care of
; setting up for the particular call and making it.
;
; I'm not sure if the utility routines are going to stay around, or are going to be
; published as required setup stuff for shells using the ATrap and CTE, or what.
; Stay tuned.
;
;------------------------------------------------------------------------------
NewTMCall
@savedregs reg d1-d7/a0-a6 ; saved registers (might as well save it all (except result reg, d0)!
movem.l @savedregs,-(sp) ; save some registers
move sr,-(sp) ; save our status
ori.w #hiIntMask,sr ; turn off interrupts
link a5,#0 ; must do this after saving the regs because
; we don't know ahead of time how much stuff we're
; going to stick on the stack
move.l (a0)+,d1 ; get the number of longs in the call
beq.s @noParams ; branch if there are none
lea (a0,d1.l*4),a0 ; go to the end of the list
subq.l #1,d1 ; adjust for dbra loop
@copy
move.l -(a0),-(sp) ; copy the items onto the stack
dbra.w d1,@copy ; and keep going until done
@noParams
lea LocalFunctions,a0 ; get the base address of the local function table
move.l d0,d1 ; make a copy of the opcode
swap d1 ; get the high word of of the opcode
cmp.w #1,d1 ; is this a utility function call? (0002 is a utility)
bne.s @UtilFunc ; branch if so
lea NewTM_Table,a0 ; else, assume we have a CTE function
@UtilFunc
move.l (a0,d0.w*4),d0 ; get the offset from base to the routine
jsr (a0,d0.l) ; make the reference absolute and make the call
unlk a5 ; get rid of how ever much stuff we put on the stack
move (sp)+,sr ; restore the status register
movem.l (sp)+,@savedregs ; and restore saved regs
rts
;------------------------------------------------------------------------------
;
; This table is for the local utility calls used by the "new" TestManager.
;
;------------------------------------------------------------------------------
LocalFunctions ; requested routine function code (d0)
; ----------------- ------------------
dc.l LclInitializeCTEandUST -LocalFunctions ; $xxx2 0000
dc.l LclGetROMBasedDTMInfo -LocalFunctions ; $xxx2 0001
;------------------------------------------------------------------------------
;
; This table takes care of the CTE calls supported by the "new" TestManager.
;
;------------------------------------------------------------------------------
NewTM_Table
CASE ON ; requested routine function code (d0)
; ----------------- ------------------
dc.l GI_InitInterface -NEWTM_TABLE ; $xxx1 0000
dc.l GI_GetVersion -NEWTM_TABLE ; $xxx1 0001
dc.l GI_AllocPermMem -NEWTM_TABLE ; $xxx1 0002
dc.l GI_AllocTempMem -NEWTM_TABLE ; $xxx1 0003
dc.l GI_FreeTempMem -NEWTM_TABLE ; $xxx1 0004
dc.l GI_GetCommentary -NEWTM_TABLE ; $xxx1 0005
dc.l GI_GetDefaultExecutionOptions -NEWTM_TABLE ; $xxx1 0006
dc.l GI_ExecuteDTM -NEWTM_TABLE ; $xxx1 0007
CASE OFF
LclGetROMBasedDTMInfo
;------------------------------------------------------------------------------
;
; This routine will take a ROM-based test and subtest ID, and a pointer to an info
; structure for each (allocated by the caller), and fill in those info structures
; based on information from the ROM-based tables of tests and subtests. This routine
; is available for shells that wish to use the ATrap to run ROM-based DTMs under
; CTE. The shell need only allocate memory for the various structures needed (this
; can be accomplished by asking the TestManager to make an AllocPermMem call and
; getting the pointer back from the TestManager), and the TestManager will take care
; of making the calls to CTE in the ROM. The advantage is that the TestManager can
; also help the shell access ROM-based DTMs, get the ROM-based info about them in
; the structures, then let the shell override some of that info (such as standard
; test params, etc.).
;
; If a shell is using a ROM-based test or subtest with a non ROM-based test or
; subtest, then it only needs the info for the ROM-based entity it is using. In
; that case, it should pass in 0 for the ID of the entity (test or subtest) that
; it doesn't need me to get the info for, and I will skip it.
;
StackFrame RECORD 0, Increment ; Starts at offset 0 into the stack
@return ds.l 1 ; Return address
@CTEInfoPtr ds.l 1 ; CTE information pointer
@SubtestID ds.l 1 ; ID of subtest to return information for
@STinfoPtr ds.l 1 ; Pointer to where to put the subtest info
@STinfoSize ds.l 1 ; size of subtest info area
@TestID ds.l 1 ; ID of the ROM-based Test
@TinfoPtr ds.l 1 ; Pointer to where to put the test info
@TinfoSize ds.l 1 ; size of test info area
ENDR
;
;------------------------------------------------------------------------------
WITH CTETestInfo, CTESubtestInfo, StackFrame
move.l @STinfoSize(sp),d0 ;get the size of the reserved area for subtest info
cmp.l #sizeofCTESubtestInfo,d0 ;is it big enough?
bge.s @STInfoAreaOK ;continue if OK
move.l #-5,d0 ;else, signal error
bra.w @exit ;and exit immediately
@STInfoAreaOK
move.l @TinfoSize(sp),d0 ;get the size of the reserved area for test info
cmp.l #sizeofCTETestInfo,d0 ;is it big enough?
bge.s @TInfoAreaOK ;continue if OK
move.l #-6,d0 ;else, signal error
bra.w @exit ;and exit immediately
ENDWITH
@TInfoAreaOK
WITH StackFrame, USTSubtest, CTEInfo, USTGlobals, CPUTestList, CTEDTMExecutionOptions
movea.l @CTEInfoPtr(sp),a0 ; get the CTEInfo pointer
movea.l executionOptions(a0),a0 ; get the execution options ptr
; get the ptr to the userInfo (which
; points to the USTGlobals)
movea.l CTEDTMExecutionOptions.userInfo(a0),a0
movea.l GlobCPUTestList(a0),a1 ; and finally, the pointer to the CPU test table
; Given the subtest ID from the user, find it in our machine-specific DTM table, make
; sure it's OK to run in this environment (ATrap), and fill in the subtestInfo
; structure information:
move.l @SubtestID(sp),d0 ; get the subtest ID
beq.s @TestSearch ; if it's zero, then get the info for the test
; and skip the subtest stuff
@CPUTestListLoop
cmp.w TLSubTest_ID(a1),d0 ; is this the one?
beq.s @foundCPUST
adda.l #sizeofCPUTestList,a1 ; go to the next entry
cmp.w #-1,TLTest_ID(a1) ; is this the end <H7><SM6>
bne.s @CPUTestListLoop ; keep looking if not
move.l #-10,d0 ; else, sigal error - subtest not found
bra.s @exit ; and exit
@foundCPUST
move.w TLrunflags(a1),d1 ; get the run flags
and.w RunMode(a0),d1 ; see if it's OK to run this
bne.s @STOK ; branch if so
move.l #-11,d0 ; else, error out
bra.s @exit
@STOK
;;; movea.l #USTSubtests,a3 ; get a pointer to the subtest list in ROM
BigLea USTSubtests,a3 ; this will only work in ROM
move.l a3,d2 ; save this for later
movea.l @STinfoPtr(sp),a1 ; get the pointer to the subtest info
; Go through the process of searching the ROM-based Subtest list for the target
; subtest ID, and load its info into the provided info structure:
@SubtestListLoop
WITH USTSubtest, CTESubtestInfo
cmp.l STSubtest_ID(a3),d0 ; is this our subtest?
beq.s @foundSTEntry ; jump if so
add.l #sizeofUSTSubtest,a3 ; go to next entry
bra.s @SubtestListLoop ; and keep looking
@foundSTEntry
move.l #0,userInfo(a1) ; fill in the user info
move.l STSubtest_ID(a3),id(a1) ; fill in the subtest ID
move.l STEntryPtr(a3),functionEntry(a1) ; fill in the entry pointer
add.l d2,functionEntry(a1) ; and de-reference it
move.l STParamSize(a3),paramsSize(a1) ; fill in the param size
move.l STResultSize(a3),resultsSize(a1) ; and the result size
ENDWITH
; Now, do the same with the Test ID, using the ROM-based Test list:
@TestSearch
move.l @TestID(sp),d0 ; get the test ID
beq.s @finished ; if it's zero, then the user wanted info
; for a subtest and not a test, so
; just skip all of this
BigLea USTTests,a3 ; get a pointer to the test information
move.l a3,d2 ; and save it here
movea.l @TinfoPtr(sp),a1 ; get a pointer to the test information to fill out
@TestListLoop
WITH USTTest, CTETestInfo
cmp.l TTest_ID(a3),d0 ; is this our test?
beq.s @foundTEntry ; jump if so
add.l #sizeofUSTTest,a3 ; go to next entry
bra.s @TestListLoop ; and keep looking
@foundTEntry
move.l #0,userInfo(a1) ; fill in the user info pointer
move.l TTest_ID(a3),id(a1) ; fill in the test ID
move.l TEntryPtr(a3),functionEntry(a1) ; fill in the entry pointer
add.l d2,functionEntry(a1) ; and de-reference it
move.l #0,paramsSize(a1) ; zero out the paramsize
move.l #0,resultsSize(a1) ; and the result size
ENDWITH
ENDWITH
@finished
moveq.l #0,d0 ;signal success
@exit
rts
LclInitializeCTEandUST
;------------------------------------------------------------------------------
;
; This is the entry point used to initialize the CTE kernel for use by the "new"
; TestManager ATrap. The ATrap is unique among the five ROM-based diagnostics
; environments (Startup/Restart, Serial Test Manager, ROM BurnIn, In House Tester
; hook, TestManager ATrap) in that it doesn't make the USTInit call (but it does
; use the USTGlobals). Also, it doesn't use a5 to keep track of the USTGlobals because
; the ATrap is running under the MacOS, where the other diagnostics environments
; are running before the OS is created and initialized (they own the Mac at that
; point). So, for a lack of an a5, the ATrap uses a little trick to keep track of
; the USTGlobals without the need to modify the CTE globals to keep a pointer in
; there (this provides for a cleaner separation of church and state, i.e., the
; ATrap and CTE). The ATrap stores the USTGlobals pointer in the userInfo field
; of the executionOptions structure, which is created as part of the CTE initialization.
; As long as the user is relying on the ATrap to handle CTE stuff, then this is
; safe. If the user wishes to modify the exeuctionOptions userInfo pointer, then
; the user is responsible for re-initializing the ATrap's environment or at least
; restoring the userInfo field to point to the USTGlobals.
;
; If an outside shell is going to be using the ATrap with CTE, it will need to
; allocate the necessary memory from the Memory Manager (remember, the ATrap is
; the only ROM-based diagnostics environment that runs while the OS is active). It
; passes a pointer to this memory and its size to this routine, which will treat it
; as the CTE workspace.
;
; CASE ON
LclInitializeCTEandUSTStackFrame RECORD 0, Increment ;Starts at offset 0 into the stack
@ReturnAddr ds.l 1 ;Caller's return address
@CTEGlobs ds.l 1 ;Pointer to the CTE globals
@CTESpaceSize ds.l 1 ;size of CTE workspace
ENDR
;
;------------------------------------------------------------------------------
WITH LclInitializeCTEandUSTStackFrame, ProductInfo, USTGlobals, CTEInfo, CTEDTMExecutionOptions
movea.l @CTEGlobs(sp),a0 ; get the CTE globals pointer
move.l @CTESpaceSize(sp),d0 ; and the size of the globals
CASE ON
GIM_InitInterface (a0), d0 ; initialize the interface
CASE OFF
movea.l @CTEGlobs(sp),a0 ; get the CTE globals again
move.l #sizeofUSTGlobals,d0 ; and the size of the USTGlobals
CASE ON
GIM_AllocPermMem (a0), d0 ; allocate our USTGlobals from CTE space
CASE OFF
movea.l @CTEGlobs(sp),a0 ; get the CTE globals again
movea.l executionOptions(a0),a0 ; get the executionOptions pointer
move.l d0,CTEDTMExecutionOptions.userInfo(a0)
; and put the USTGlobals pointer in the
; userInfo field of the CTE
; executionOptions structure, where the
; ROM-based Test can find it (if the
; ROM-based Test is being used...if not,
; then the user can change the userInfo
; field if needed)
movea.l d0,a1 ; and put the USTGloblas pointer here for
; immediate use (this routine only)
movea.l @CTEGlobs(sp),a0 ; get the CTE globals again
movem.l a0-a1,-(sp) ; save our registers
move.l #gestaltProcessorType,d0 ; find out the processor type we're on
_Gestalt ; ask gestalt for the info
tst.w d0 ; any errors?
beq.s @OkProc ; if not, return result
moveq #envCPUUnknown,a0 ; oh well, use SysEnvs bad way of saying
; "unknown processor type"
@OkProc
move.w a0,d0 ; save the processor type from Gestalt
; IS THIS CORRECT? IS a0 THE RETURN VALUE
; FROM GESTALT???
movem.l (sp)+,a0-a1 ; get our registers back
move.l d0,processorType(a0) ; save the processor type
; Fill out the rest of the USTGlobals structure for use by the ATrap:
movea.l UnivInfoPtr,a2 ; get the pointer to the universal information
; (this is a lowmem global that points to the
; ProductInfo structure)
moveq.l #0,d1 ; zero out a register
move.b ProductKind(a2),d1 ; get the boxflag
;;; The boxflag is never used in Scott's ATrap stuff, so I'm going to comment it out
;;; for now, and remove it if it turns out to be unnecessary.
;;;
;;; move.l d1,boxFlag(a0) ; store it
move.w #RunBits.ATrap,RunMode(a1) ; store our environment flag
move.l a0,CTEGlobals(a1) ; store a pointer to the CTE kernel
move.l #0,ErrorHandler(a1) ; zero out the error handler pointer
move.l a2,PrdctInfPtr(a1) ; get a pointer to the product info pointer
movea.l (a2),a3 ; get a pointer to the decoderinfo record
adda.l a2,a3 ; dereference it
move.l a3,DcdrInfPtr(a1) ; put it in our local area
move.l AddrMapFlags,BasesValidFlags(a1) ; and store the bases valid flags
; (AddrMapFlags is a lowmem global
; that contains the bit numbers of
; BasesValid flags)
WITH CPUList, CPUTestList
;;; movea.l #USTCPUList,a0 ; a move for now, a load when it gets to ROM
BigLea.l USTCPUList,a0 ; start at the beginning of the list of tables
move.l a0,d3 ; save this for later
@itemloop
move.w cpuBoxFlag(a0),d2 ; Get the box flag for this test table
cmp.b #boxUnknown,d2 ; Is this the end of the table?
beq.s @found ; quit if so - we'll use the default tests
cmp.b d2,d1 ; is this the table entry for this machine?
beq.s @found ; quit if so
addq.l #sizeofCPUList,a0 ; else, go to the next table entry
bra.s @itemloop ; and keep looking
@found
movea.l CPUTestListPtr(a0),a0 ; get a pointer to the test table for this CPU
lea.l (a0,d3.l),a0 ; and dereference it
move.l a0,GlobCPUTestList(a1) ; and store it in our global area
ENDWITH
ENDWITH
moveq.l #0,d0 ; clear out the return status
rts
ENDPROC