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

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

3251 lines
122 KiB
Plaintext

;
; 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: © 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.
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Pre-Terror ROM comments begin here.
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; <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µ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>
; ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ <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µ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
;
;---------------------------------------------------------------------------
; ¥¥¥TJump dc.w SizeMem-TJump ;Test #0 = SizeMemory <18>
; ¥¥¥ dc.w DataBusTest-TJump ;Test #1 = DataBusTest
; ¥¥¥ dc.w Mod3Test-TJump ;Test #2 = Mod3Test <1.4>
; ¥¥¥ dc.w AddrLineTest-TJump ;Test #3 = AddrLineTest
; ¥¥¥ dc.w RomTest-TJump ;Test #4 = ROMTest <1.4>
; ¥¥¥ dc.w RevMod3Test-TJump ;Test #5 = RevMod3Test <1.4>
; ¥¥¥ dc.w ExtRAMTest-TJump ;Test #6 = ExtRAMTest
; ¥¥¥ dc.w MovInvTest-TJump ;Test #7 = MovInvTest <18>
; ¥¥¥ dc.w SizeV8VRAMShell-TJump ;Test #8 = Size the Video RAM <35>
; ¥¥¥ dc.w NoTest-TJump ;Test #9 = NoTest
; ¥¥¥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 ³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 "³ 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
;¥¥¥ move.w (a5,d1.w),d1 ;fetch test offset from table
;¥¥¥ 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
;¥¥¥ move.w 0(a5,d1.w),d1 ;fetch test offset from table <v1.0>
;¥¥¥ 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µ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µ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
; ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
; 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ª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