sys7.1-doc-wip/OS/StartMgr/USTEnvirons.a
2019-07-27 22:37:48 +08:00

2236 lines
93 KiB
Plaintext

;__________________________________________________________________________________________________
;
; File: USTEnvirons.a
;
; Contains: This file contains routines which perform necessary housekeeping
; in order to run tests in the ROM. They also provide the interface
; between the serial test manager and the ROM based CTE kernel.
;
; Written by: Scott Smyers
;
; Copyright: © 1990, 1992-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM5> 9/13/93 SAM Added a flag to USTInit to tell it not to call SizeMem (again!).
; <SM4> 11/3/92 rab Roll in Horror changes. Comments Follow:
; <H12> 7/27/92 AL Fixed the IHT setup for the Address Line Test, which changed
; when SizeMemory changed (see comments in USTCritTests.a).
; <H11> 7/15/92 AL Fixed the UTEReturnTestInfo and UTEReturnSubtestInfo functions
; to work correctly, modified some comments to be more accurate.
; <H10> 7/9/92 AL Did some fine tuning of a few routines for STM and the IHT hook.
; <H9> 07-07-92 jmp Fixed previous check-in comments.
; <H8> 07-07-92 jmp Had to conditionally remove the BigBSR to DataBusTest
; due to an assembler error when the -ram option is
; used. Anyone know/care why?
; <H7> 7/1/92 AL Fixed a couple of things in the IHT hook. Preserving the
; environment across IHT_Init and fixing a small stack
; messer-upper is about it. Added some more comments for fun and
; enjoyment.
; <H6> 6/17/92 AL Fixed the UTEExecuteDTM routine to correctly access a couple of
; variables relative to the stack.
; <H5> 6/7/92 AL Fixed a minor problem with a couple of <H4> comments that
; weren't separated from the code, which could possibly cause an
; assembly process anomoly.
; <H4> 6/7/92 AL Added some comments to help demistify some of the sources. Fixed
; the environment checking logic to find and execute the correct
; tests for the given situation (startup, restart, etc.). Fixed
; the critical test access mechanism for the IHT hook.
; <SM3> 9/25/92 RB Changed a BSR6 macro to jump.
; <SM2> 5/2/92 kc Roll in Horror. Comments follow:
; <H3> 3/6/92 AL 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 USTTestMgr.a into it. It takes a little less
; than 16k from OverPatch1.a, and currently uses about 6k.
; Other changes include the removal of all obsolete pre-CTE v2.1
; routines and references. Made the conversion to CTE v2.1. Added
; greater functionality to the Serial Test Manager and Board
; Tester Hook (IHT) to support the new CTE. Enhanced some of the
; comments to more accurately reflect what the code is actually
; doing.
; <H2> 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.
; ———————————————————————————————————————————————————————————————————————————————————————
; Pre-Horror ROM comments begin here.
; ———————————————————————————————————————————————————————————————————————————————————————
; <7> 4/22/91 BG Rolling in Scott Smyers changes: restore the diagnostic ROM
; entry point before returning to the IHT ROMs, and other fixes to
; this hook. Also, added the raw cte install test and subtest
; calls to the CTE dispatch table for use by IHT code.
; <6> 4/13/91 BG Rolling in Scott Smyers changes: Added the board tester ROM hook
; code to this file from USTTestMgr.a. In the process, I changed
; the code so that it leverages off of the new CTE engine I added
; to the Serial test manager. That engine is in this file, so
; that's why I moved it.
; <5> 4/2/91 CCH Rolled in Scott Smyers' changes: Added support for new test list
; structure element names. Made the "install test" algorithm into
; a loop to install all ROM based tests.
; <4> 3/13/91 CCH Rolled in RBI changes from Scott Smyers.
; <3> 1/24/91 CCH Rolled in changes from Scott Smyers.
; <2> 1/14/91 CCH Rolled in Scott Smyers' changes.
; <1> 12/14/90 HJR Adding for the first time.
;
;__________________________________________________________________________________________________
TITLE 'USTEnvirons.a'
CASE OFF
EnvironProc PROC
IMPORT SizeMemory
IMPORT JGetHardwareInfo
IMPORT USTCPUList
IMPORT USTSubtests
IMPORT USTInit
IMPORT CopyPRAMToRAM
IMPORT CopyRAMToPRAM
IMPORT GetChar
IMPORT OutChar
IMPORT Mod3Test ; <H4><SM4>
IMPORT RevMod3Test ; <H4><SM4>
IMPORT RomTest ; <H4><SM4>
IMPORT StartUpROMTest ; <H4><SM4>
IMPORT ExtRAMTest ; <H4><SM4>
IMPORT AddrLineTest ; <H4><SM4>
IMPORT DataBusTest ; <H4><SM4>
IMPORT dynamic_bussize_test ; <H4><SM4>
IMPORT GI_InitInterface
IMPORT GI_GetVersion
IMPORT GI_ExecuteDTM
IMPORT GI_AllocPermMem
IMPORT GI_AllocTempMem
IMPORT GI_FreeTempMem
IMPORT ClkWpOff
IMPORT USTCPUList
IMPORT USTTests
IMPORT TJump ; <SM4>
EXPORT USTMainTest
EXPORT SetupForExecuteDTM
EXPORT UTECmd
EXPORT diagROMentry
; These equates are used by the UTEReturnTestInfo and UTEReturnSubtestInfo functions. They <SM4>
; are defined in the OPPOSITE order of the USTTest and USTSubtest structure definitions, <SM4>
; because they are used to place the USTTest entries on the stack as local variables <SM4>
; in preparation for the SendData call. Local variables are referenced with negative <SM4>
; offsets from the stack frame pointer (in this case, it's going to be A5): <SM4>
resultSizeLoc equ -4 ; this many bytes off of A5, for the SendData routine <H11><SM4>
paramSizeLoc equ -8 ; this many bytes off of A5, for the SendData routine <H11><SM4>
codeSizeLoc equ -12 ; this many bytes off of A5, for the SendData routine <H11><SM4>
namePtrLoc equ -16 ; this many bytes off of A5, for the SendData routine <H11><SM4>
testAddrLoc equ -20 ; this many bytes off of A5, for the SendData routine <H11><SM4>
testIDSizeLoc equ -24 ; this many bytes off of A5, for the SendData routine <H11><SM4>
USTMainTest
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine is the test in the ROM. This routine is CTE Type 2 style. When
; executed it sets up the registers as needed for the ROM based subtests, then calls
; the requested ROM subtest using the BSR6 convention. Note that although this is a
; CTE style test in as much as the stack has the expected parameters for a CTE test,
; none of the ROM-based noncritical tests (subtests in CTE lingo) use these values. In
; fact, all they need are the decoder and product info ptrs, and the bases valid flags.
; However, for the sake of conformity future enhancement to the ROM-based non critical
; subtests and stuff like that, this routine is setup to be like a real CTE test.
;
; Input: Information on the stack according to the following format:
;
USTTestCallStack RECORD 0,increment
@A6Link ds.l 1 ; saves space for the "linked" A6
@ReturnAddr ds.l 1 ; caller's return address
@CTEGlobs ds.l 1 ; pointer to the CTE globals
@testParams ds.l 1 ; pointer to the test parameter block
@testResults ds.l 1 ; pointer to the test result block
@subtestParams ds.l 1 ; pointer to subtest parameter block
@SubTestID ds.l 1 ; subtest ID
ENDR
;
; Output:
; Executes a test
;
;----------------------------------------------------------------------
@savedRegs reg a0-a5/d1-d7
WITH USTSubtest, USTGlobals, ProductInfo, USTTestCallStack
link a6,#0
movem.l @savedRegs,-(sp) ; save these during this operation
movea.l @CTEGlobs(a6),a3 ; get a pointer to the globals so I can get to
movea.l a3,a4 ; the HW info, and save this for later
; All of the ROM-based non-critical tests expect a0, a1, d0 and d2 to be pointing to
; some valid information on entry. Therefore, these registers must be setup before
; jumping into the subtest. The Terror ROM had the CTE globals modified to include
; access to this information, but there is a way to do it while maintaining compatibility
; with the stock CTE. That way is to use the userInfo pointer of the ExecutionOptions
; parameter to ExecuteDTM to hold a pointer to the USTGlobals structure (which contains
; the necessary hardware info). This test can look through the CTE globals to the
; ExecutionOptions field, then through this field to the USTGlobals:
; CASE ON ; if this is disabled, things build better...
WITH CTEInfo, CTESubtestInfo, CTEDTMExecutionOptions
movea.l subtestInfo(a3),a3 ; get a ptr to the subtest info...
movea.l functionEntry(a3),a3 ; and get the entry point
movea.l executionOptions(a4),a4 ; get the execution options ptr
; get the ptr to the userInfo (which
; points to the USTGlobals)
movea.l CTEDTMExecutionOptions.userInfo(a4),a4
ENDWITH
; CASE OFF
; Here's where the actual hardware info registers are filled in:
move.l BasesValidFlags(a4),d0 ; get the bases valid flags
movea.l DcdrInfPtr(a4),a0 ; and decoder info pointer for tests
movea.l PrdctInfPtr(a4),a1 ; and product info pointer
move.w ProductKind(a1),d2 ; get our box flag and decoder kind info
; Now prepare to execute the subtest and return the results:
moveq.l #0,d6 ; zero out the result register
movem.l a6,-(sp) ; save our registers
lea @1,a6 ; setup return address <SM3> rb
jmp (a3) ; and execute the subtest <SM3> rb
@1 ; <SM3> rb
movem.l (sp)+,a6 ; restore our registers
move.l d6,d0 ; return with error code (the result from a
; C function should be in D0, and since this
; is simulating a C function, put it there)
movem.l (sp)+,@savedRegs ; restore all registers
unlk a6
rts ; and return
ENDWITH
; End of USTMainTest
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This table (STM_Util) holds relative entry points to utility functions used by the
; Serial Test Manager (STM), to facilitate STM-specific operations, including the
; use of the CTE kernel. There is a separate table, GI_Table, which contains relative
; entry points for the GenericInterface routines used to manipulate the CTE environment.
;
;
STM_Util
dc.l UTEReset -STM_Util ; Init or re-init the CTE kernel (MUST BE FIRST!!!)
dc.l UTEExecuteDTM -STM_Util ; execute a DTM given the test & subtest IDs
dc.l UTEDownloadTest -STM_Util ; download a test
dc.l UTEDownloadSubtest -STM_Util ; download a subtest
dc.l UTEDownloadExecutionOptions -STM_Util ; download an execution options structure
dc.l UTEDownloadExecutionResults -STM_Util ; download an execution results structure
dc.l UTEDumpRAM -STM_Util ; dump a section of RAM to the host
dc.l UTEReadPRAM -STM_Util ; read an area of PRAM <T4>
dc.l UTEWritePRAM -STM_Util ; write an area of PRAM <T4>
dc.l UTEReturnTestInfo -STM_Util ; return the vital statistics of a given
; ROM-based test
dc.l UTEReturnSubtestInfo -STM_Util ; do the same for a subtest
STM_UtilSize equ (*-STM_Util)>>2 ; number of jump table entries
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This table (GI_Table) contains relative entry points for the GenericInterface
; routines used to manipulate the CTE environment. It is used by both the Serial Test
; Manager (STM) and In-House Tester hook (IHT - sometimes known as the board testers
; or diagnostic ROMs).
;
; These environments would use this table to access the GI_ExecuteDTM call directly
; only if they wanted to take care of their own DTMs (setting up the testInfo,
; subtestInfo, executionOptions structures, etc.) that are NOT in the system ROM,
; and just use the STM/IHT hooks to handle making the calls to the Generic Interface.
;
; When they want to execute DTMs that exist in the ROM, all they need to do is
; request the special DiagExecuteDTM (for the IHT hook) or UTEExecuteDTM (for STM)
; routines and supply the test and subtest IDs. Those two routines can take care of
; the rest of the work (setting up the structures, etc.).
;
GI_Table
CASE ON
; These are the ID values as
; documented in the STM manual
dc.l GI_InitInterface -GI_TABLE ;100
dc.l GI_GetVersion -GI_TABLE ;101
dc.l GI_AllocPermMem -GI_TABLE ;10B
dc.l GI_AllocTempMem -GI_TABLE ;10C
dc.l GI_FreeTempMem -GI_TABLE ;10D
dc.l GI_GetCommentary -GI_TABLE ; ?????
dc.l GI_GetDefaultExecutionOptions -GI_TABLE ; ?????
dc.l GI_ExecuteDTM -GI_TABLE ; ?????
CASE OFF
GI_TableSize equ *-GI_Table
;----------------------------------------------------------------------
UTECmd
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This is the entry point for the interface to the serial test manager "!" commands.
; The "*" commands are handled in the USTTestMgr.a source file. This code receives
; the CTE command string, decodes it, then executes the selected command. The format
; of the command string is as follows:
;
; !<offset><# params><params><other>
;
; Where: <offset> - (long) Command number (offset into jump table below)
; <# params> - (word) Number of bytes to receive for calling params
; <params> - (longs) Parameters for command, must agree with <# params>
; <other> - (bytes) Other information, such as test/subtest code
;
; This routine assumes that the stack is pointing to somewhere useful. If an
; initialize command is received, the stack will be moved around.
;
; If the command received is not an initialize command, this code assumes that the
; UTEReset command has already been executed, and that the stack looks like this (the
; UST Globals pointer is the first item on the stack):
;
GICodeBase equ $10000 ;base number for GI routines
cmdBytes equ 6
;
StackFrame1 RECORD 0, Increment ;Starts at offset 0 into the stack
@return ds.l 1 ;Return address
@myGlobs ds.l 1 ;Our local global data
ENDR
;
;
; Note that the various STM_Util routines have different stack frame needs. Some calls
; don't need any information added to the stack beyond what is already here when this
; routine is entered. Others need a substantial amount of information set up on the
; stack. So, the burning question is: WHO sets up the stack for these calls? The
; burning answer is: THIS ROUTINE, BASED ON THE COMMAND LINE FROM STM.
;
; Here's how it works. In the command line prototype above, the #params field gives
; me the number of bytes that will be coming in for the particular request. It is the
; responsibility of the user (whether that be a person using MacTerminal to control
; STM or running a diagnostics tool that provides a friendly interface to STM or
; whatever) to provide this information when typing in the command. From here, I can
; pick that information from the serial port, push it on the stack, and make the
; necessary utility call. It's as simple as that.
;----------------------------------------------------------------------
WITH StackFrame1, USTGlobals
lea -cmdBytes(sp),sp ;make room for our command number
move.l sp,-(sp) ;and store a pointer to it on the stack
move.l #cmdBytes,-(sp) ;command # is 4 bytes (1 long)
bsr GetCmdData ;then get the command number
lea 8(sp),sp ;pop off our stack data
move.l (sp)+,d0 ;then get the command number
bne.s @notInit ;continue if this is not a reset
addq.l #2,sp ;else pop off the command stack frame size
movea.l @return(sp),a6 ;Get the return address (init returns directly to caller)
lea STM_Util,a0 ;get the pointer to the jump table
adda.l (a0),a0 ;offset to init routine (adjust address to absolute)
jmp (a0) ;and go init
@notInit
moveq.l #0,d1 ;clear d1 first
move.w (sp)+,d1 ;get the command stack frame size
movea.l @myGlobs(sp),a5 ;Get our globals pointer
movem.l a3/d3,-(sp) ;save our SCC registers for after the call
move.l d0,CmdNumber(a5) ;Save the command number
move.l d1,CallFrameSize(a5);and get the stack frame size
beq.s @CmdDecode ;continue if no additional data to fetch
suba.l d1,sp ;get ready to receive the stack information
move.l sp,-(sp) ;save a pointer to the area on the stack
move.l d1,-(sp) ;and save the number of bytes to get
bsr GetCmdData ;get the data
lea 8(sp),sp ;pop off our stack data
move.l CmdNumber(a5),d0 ;retrieve the command number
@CmdDecode
lea STM_Util,a0 ;Assume utility function
cmp.l #GICodeBase,d0 ;is this a GI call?
blt.s @Branch ;continue if not
lea GI_Table,a0 ;else, get the base address of the GI table
sub.l #GICodeBase,d0 ;and adjust the base of the cmd #
; Need to do some range checking here to see if we want to use the ROM or the
; RAM based jump table.
;
; NOTE: the previous comment was in the original sources, but I have no idea what
; it means.
@Branch
move.l CTEGlobals(a5),-(sp);all CTE rouines expect the globs pointer first
lsl.l #2,d0 ;adjust the offset
move.l (a0,d0.l),d0 ;get the jump table entry (a relative entry at this point)
jsr (a0,d0.l) ;and dispatch to proper point (adjusted to absolute)
addq.l #4,sp ;pop off the CTE globs
adda.l CallFrameSize(a5),sp;pop our data off the stack
movem.l (sp)+,a3/d3 ;restore the SCC information
ENDWITH
move.l d0,-(sp) ;put data to report on the stack
move.l sp,-(sp) ;put the address of the data on the stack
move.l #4,-(sp) ;and the number of bytes to send
bsr SendData ;send out the contents of d0
lea 8(sp),sp ;pop our stuff off the stack
moveq.l #0,d0 ;clear the return status
move.l (sp)+,d6 ;put the return status into the result register
beq.s @finish ;did we have an error?
move.b #'X',d0 ;Signal the world if so
@finish
rts ;and return
; End of UTECmd
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEReset
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; UTEReset creates a fresh set of UST globals and CTE globals. It should only
; be called once, after memory has been tested and validated. In the process, this
; routine calls USTInit, which will size memory and set up the stack. So, this is
; where it all begins. When we're done here, we go back to the entity that called
; the UTECmd routine in the first place; there is no further interaction with the
; STM stuff until the entity starts requesting operations.
;
; NOTE: The BSR6 to USTInit was changed to a BigBSR6 because this file was taken
; out of USTStartTest.a and put into USTStartTest1.a, and the branch became too
; far for a BSR6. HAL 2/12/92
;
WITH USTGlobals
move.l a6,usp ; save the return address
move #0,D2 ; Tell USTInit to call SizeMem <SM5>
BigBSR6 USTInit,a0 ; Initialize the universal environment <T7>
move.w #RunBits.STM,RunMode(a5) ; set the run mode for serial test manager
suba.l #SizeOfCTEGlobals,sp ; allocate our CTE global area on the stack
move.l sp,CTEGlobals(a5) ; save the global area pointer
move.l a5,-(sp) ; save our global pointer
move.l usp,a0 ; now put the return address on the stack
move.l a0,-(sp)
movea.l CTEGlobals(a5),a0 ; get the globs pointer
CASE ON
GIM_InitInterface (a0),#SIZEOFCTEGLOBALS ; init the CTE interface
CASE OFF
ENDWITH
rts ; this returns directly to the caller of UTECmd
; End of UTEReset
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEDumpRAM
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine sends a section of RAM to the host. The start address and
; size of the transfer are specified in the calling sequence.
;
; The following record describes the stack on input to this routine:
StackFrame2 RECORD 0, Increment ;Starts at offset 0 into the stack
@return ds.l 1 ;Return address
@CTEGlobs ds.l 1 ;Pointer to CTE globals (not used here)
@startAddr ds.l 1 ;Start address of RAM to dump
@size ds.l 1 ;number of bytes to dump
ENDR
;
;----------------------------------------------------------------------
WITH StackFrame2
movea.l sp,a0
move.l @startAddr(a0),-(sp) ;put the start address on the stack
move.l @size(a0),-(sp) ;and the size
bsr SendData ;transmit the data
lea 8(sp),sp ;pop the data off the stack
ENDWITH
moveq.l #0,d0 ;clear the return status
rts
; End of UTEDumpRAM see <T4> below
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEReadPRAM
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine reads a section of PRAM and sends it to the host. The start address and
; size of the transfer are specified in the calling sequence.
;
; The following record describes the stack on input to this routine:
StackFrame3 RECORD 0, Increment ;Starts at offset 0 into the stack
@savedA6 ds.l 1 ;location for "linked" A6 register
@return ds.l 1 ;Return address
@CTEGlobs ds.l 1 ;Pointer to CTE globals (not used here)
@startAddr ds.w 1 ;Start address of PRAM to dump
@size ds.w 1 ;number of bytes to dump
ENDR
;
;----------------------------------------------------------------------
WITH StackFrame3, USTGlobals
link a6,#0 ;get our stack frame pointer
movea.l DcdrInfPtr(a5),a0 ;get the pointer to the decoder info
movea.l PrdctInfPtr(a5),a1 ;and the product info
movea.l DecoderInfo.VIA1Addr(a0),a2 ;then get the VIA1 pointer
suba.w @size(a6),sp ;make room for the data in RAM
movea.l sp,a4 ;get the address of this area
movem.l d3/a3-a4/a6,-(sp) ;save our local variables
move.w @startAddr(a6),a3 ;get the PRAM source address <H8><SM4>
move.w @size(a6),d3 ;get the size <H8><SM4>
_CopyPRAMToRAM a3, (a4), d3 ;go read PRAM <H8><SM4>
movem.l (sp)+,d3/a3-a4/a6 ;and restore our local variables
movem.l a6,-(sp) ;save our local data pointer
move.l a4,-(sp) ;now: send the data to the serial port
move.w @size(a6),d0 ;get the number of bytes to move
ext.l d0 ;make it a long
move.l d0,-(sp) ;put the size on the stack
bsr SendData ;transmit the data
lea 8(sp),sp ;pop the data off the stack
movem.l (sp)+,a6 ;restore our local pointer
unlk a6 ;restore the stack
ENDWITH
moveq.l #0,d0 ;clear the return status
rts
; End of UTEReadPRAM
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEWritePRAM
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine receives data from the host and writes it to PRAM. The start
; address and size of the transfer are specified in the calling sequence.
;
; The following record describes the stack on input to this routine:
StackFrame4 RECORD 0, Increment ;Starts at offset 0 into the stack
@savedA6 ds.l 1 ;saved a6 location (used in LINK instruction)
@return ds.l 1 ;Return address
@CTEGlobs ds.l 1 ;Pointer to CTE globals (not used here)
@startAddr ds.w 1 ;Start address (in PRAM) to receive data
@size ds.w 1 ;number of bytes to dump
ENDR
;
;----------------------------------------------------------------------
WITH StackFrame4, USTGlobals
link a6,#0 ;get our stack frame pointer
move.w @size(a6),d0 ;get the number of bytes to fetch
ext.l d0 ;make it a long
suba.l d0,sp ;make some room on the stack for the data
movea.l sp,a4 ;save the address of the pointer
movem.l a4/a6,-(sp) ;save our stack frame pointer
move.l a4,-(sp) ;put address of an area to hold the data
move.l d0,-(sp) ;put the number of bytes to fetch on the stack
bsr GetCmdData ;go get the data
lea 8(sp),sp ;restore the stack
movem.l (sp)+,a4/a6 ;and get our stack frame pointer again
movea.l DcdrInfPtr(a5),a0 ;get the pointer to the decoder info
movea.l PrdctInfPtr(a5),a1 ;and the product info
movea.l DecoderInfo.VIA1Addr(a0),a2 ;then get the VIA1 pointer
movem.l a4-a6,-(sp) ;save our local registers
BigBSR6 ClkWpOff,a4 ;turn off the write protect bit
movem.l (sp)+,a4-a6 ;and restore our regs
movem.l a6,-(sp) ;save our local data pointer
_CopyRAMToPRAM (a4), @startAddr(a6), @size(a6) ;write the data to PRAM
movem.l (sp)+,a6 ;restore our local pointer again
unlk a6 ;clean it up and go home
ENDWITH
moveq.l #0,d0 ;clear the return status
rts
; End of UTEWritePRAM <T4>^
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEExecuteDTM
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine gives the host one-stop-shopping for executing ROM-based DTMs. All the
; user needs to know are the test and subtest IDs, and this routine does the rest.
; Accordingly, the stack needs to be formatted to hold the two IDs. The stack is
; setup by the UTECmd routine, based on the user's input stream that comes into the
; serial port.
;
; NOTE: Like many of the CTE-related routines that support the Serial Test Manager,
; some assumptions have to be made. One of those is that the user (host machine) has
; previously requested that memory tests be executed and determined that memory is
; OK. Once memory tests have been executed, the CTE world should be initialized by
; calling the STM and requesting the UTEReset routine. After that, any more memory
; testing will wipe out CTE so it will have to be initialized all over again.
;
; Another assumption is that a5 points to the USTGlobals structure, which it should
; if the user has already called the UTEReset routine.
;
; Inputs:
StackFrame5 RECORD 0, Increment ; Starts at offset 0 into the stack
@savedReg ds.l 1 ; place to hold the saved value for the link <H8><SM4>
@return ds.l 1 ; return address is first
@CTEGlobs ds.l 1 ; CTE globals pointer is next
@subTestID ds.l 1 ; ROM-based subtest ID
@testID ds.l 1 ; ROM-based test ID
ENDR
;
;----------------------------------------------------------------------
@savedRegs reg a0-a5/d1-d5
link a6,#0 ; <H8><SM4>
movem.l @savedRegs,-(sp) ; save these during this operation
WITH StackFrame5, USTGlobals
move.l @subTestID(a6),d4 ; prepare for the SetupForExecuteDTM call <H6><H8><SM4>
move.l @testID(a6),d5 ; <H6><H8><SM4>
move.l a6,-(sp) ; save this across the next call <H8><SM4>
bsr6 SetupForExecuteDTM ; do a RAM-less bsr to the routine that takes
; care of setting up for the execution of a DTM
move.l (sp)+,a6 ; restore my stack frame pointer <H8><SM4>
; Check for errors in setting up for the ExecuteDTM and don't try to execute the DTM
; if any were found:
cmp.l #-1,tInfoFunctionEntry(a5) ; -1 in this field means test not found
beq.s @LogError
cmp.l #-1,sInfoFunctionEntry(a5) ; -1 in this field means subtest not found
beq.s @LogError
movea.l @CTEGlobs(a6),a0 ; get the CTE globals pointer for GIM_ExecuteDTM <H8><SM4>
CASE ON ; everything's OK, so do the DTM thing
GIM_ExecuteDTM (a0), EXOPUSERINFO(a5), TINFOUSERINFO(a5), SINFOUSERINFO(a5), EXRESERR(a5)
CASE OFF
bra.s @End ; go clean up the stack and return the results
ENDWITH
@LogError
move.l #-1,d6 ; return -1 indicating that either the test
; or subtest doesn't apply to this machine (or
; was not found, or can't be run from STM for
; some reason)
@End
movem.l (sp)+,@savedRegs ; restore them registers
unlk a6 ; clean it up and go home <H8><SM4>
move.l d6,d0 ; return any error
rts
; End of UTEExecuteDTM
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEDownloadTest
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine is used to handle downloading tests from the host (usually another
; Mac running a communications program like MacTerminal, but it could be just any
; old black box). This glue routine receives the calling parameters for
; GI_InstallTest (just so it can get the size of the downloaded code and the
; test ID for later reference), allocates memory for the downloaded code,
; receives the downloaded code, then adds the test info (ID and entry point - as
; determined by this routine) to a RAM-based table that will be used to execute DTMs
; when requested by the host. DTM execution will be requested by asking for the
; test and subtest IDs.
;
; NOTE: Like many of the CTE-related routines that support the Serial Test Manager,
; some assumptions have to be made. One of those is that the user (host machine) has
; previously requested that memory tests be executed and determined that memory is
; OK. Once memory tests have been executed, the CTE world should be initialized.
; After that, any more memory testing will wipe out CTE so it will have to be started
; all over again.
;
; Inputs:
StackFrame6 RECORD 0, Increment ; starts at offset 0 into the stack
@return ds.l 1 ; return address
@globs ds.l 1 ; CTE Global pointer
@TestID ds.l 1 ; ID for downloaded test
@TestPtr ds.l 1 ; not included as input
@Size ds.l 1 ; size of test to download (in bytes)
@NamePtr ds.l 1 ; not used, should be zero
@TestUserInfo ds.l 1 ; the userInfo pointer
@pbSize ds.l 1 ; the test parameter block size
@rbSize ds.l 1 ; the test result block size
ENDR
;
;----------------------------------------------------------------------
WITH StackFrame6, USTGlobals
movea.l @globs(sp),a0 ; get the CTE globals pointer
move.l @size(sp),d0 ; get the size of the test
CASE ON
GIM_AllocPermMem (a0), d0 ; allocate the necessary memory from CTE
CASE OFF
tst.l d0 ; is everything OK? (d0 = 0 means no memory available)
bne.s @allocOK ; continue if OK
moveq.l #-1,d0 ; report problems with allocation
bra.s @error ; and error out
@allocOK
move.l @size(sp),d1 ; get the size of test
move.l d0,-(sp) ; put the memory pointer on the stack
move.l d1,-(sp) ; put the memory size on the stack
bsr GetCmdData ; and receive the test code
move.l (sp)+,d1 ; get the size back
movea.l (sp)+,a0 ; and the test code pointer
; Fill in the testInfo structure of the USTGlobals in anticipation of someday trying
; to execute this test as part of a DTM. Note that I'm bypassing the normal way
; of doing this (which is to call SetupForExecutDTM) because I am working with
; downloaded Tests and Subtests, not ROM-based ones (the SetupForExecuteDTM routine
; only works with the ROM-based DTMs):
move.l a0,tInfoFunctionEntry(a5) ; the entry point
move.l @testID(sp), tInfoID(a5) ; the test ID
move.l @TestUserInfo(sp),tInfoUserInfo(a5) ; the userInfo field
move.l @pbSize(a0),tInfoParamsSize(a5) ; the paramsSize field
move.l @rbSize(a0),tInfoResultsSize(a5) ; the resultsSize field
@error
move.l d0,d6 ; this is either the address of the downloaded
; test (as determined by GI_AllocPermMem) or
; -1, meaning that not enough memory was available
ENDWITH
rts
; End of UTEDownloadTest
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEDownloadSubtest
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine is used to handle downloading subtests from the host (usually another
; Mac running a communications program like MacTerminal, but it could be just any
; old black box). This glue routine receives the calling parameters for
; GI_InstallSubtest (just so it can get the size of the downloaded code and the
; subtest ID for later reference), allocates memory for the downloaded code,
; receives the downloaded code, then adds the subtest info (ID and entry point - as
; determined by this routine) to a RAM-based table that will be used to execute DTMs
; when requested by the host. DTM execution will be requested by asking for the
; test and subtest IDs.
;
; NOTE: Like many of the CTE-related routines that support the Serial Test Manager,
; some assumptions have to be made. One of those is that the user (host machine) has
; previously requested that memory tests be executed and determined that memory is
; OK. Once memory tests have been executed, the CTE world should be initialized.
; After that, any more memory testing will wipe out CTE so it will have to be started
; all over again.
;
; Inputs:
StackFrame7 RECORD 0, Increment ; starts at offset 0 into the stack
@return ds.l 1 ; return address
@globs ds.l 1 ; CTE Global pointer
@SubtestID ds.l 1 ; ID for downloaded subtest
@SubtestPtr ds.l 1 ; not included as input
@Size ds.l 1 ; size of subtest to download (in bytes)
@NamePtr ds.l 1 ; not used, should be zero
@SubtestUserInfo ds.l 1 ; the userInfo pointer field
@pbSize ds.l 1 ; parameter block size
@rbSize ds.l 1 ; result block size
ENDR
;
;----------------------------------------------------------------------
WITH StackFrame7, USTGlobals
movea.l @globs(sp),a0 ; get the CTE globals pointer
move.l @size(sp),d0 ; get the size of the subtest
CASE ON
GIM_AllocPermMem (a0), d0 ; allocate the necessary memory
CASE OFF
tst.l d0 ; is everything OK? (d0 = 0 means no memory available)
bne.s @allocOK ; Continue if OK
moveq.l #-1,d0 ; report problems with allocation
bra.s @error ; and error out
@allocOK
move.l @size(sp),d1 ; get the size of subtest
move.l d0,-(sp) ; put the memory pointer on the stack
move.l d1,-(sp) ; put the memory pointer on the stack
bsr GetCmdData ; and receive the subtest code
move.l (sp)+,d1 ; get the size back
movea.l (sp)+,a0 ; and the subtest code pointer
; Fill in the subtestInfo structure of the USTGlobals in anticipation of someday trying
; to execute this subtest as part of a DTM. Note that I'm bypassing the normal way
; of doing this (which is to call SetupForExecutDTM) because I am working with
; downloaded Tests and Subtests, not ROM-based ones (the SetupForExecuteDTM routine
; only works with the ROM-based DTMs):
;;;;; HAL HAL HAL AARON AARON WARNING WARNING
;;;;; NOTE Make sure to support the Standard Test Params thing if necessary.
move.l a0,sInfoFunctionEntry(a5) ; the entry point
move.l @SubtestID(sp), sInfoID(a5) ; the test ID
move.l @SubtestUserInfo(sp),sInfoUserInfo(a5) ; the userInfo field
move.l @pbSize(a0),sInfoParamsSize(a5) ; the paramsSize field
move.l @rbSize(a0),sInfoResultsSize(a5) ; the resultsSize field
ENDWITH
@error
;;;;; HAL HAL HAL AARON AARON WARNING WARNING
;;;;; NOTE Check to make sure what the returned address of the allocated perm mem is
; from GI_AllocPermMem (is it in d0 or a0)? Also, make sure that registers are
; used so that nothing is lost - the macros use a0, etc.
move.l d0,d6 ; this is either the address of the downloaded
; subtest (as determined by GI_AllocPermMem) or
; -1, meaning that not enough memory was available
rts
; End of UTEDownloadSubtest
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEDownloadExecutionOptions
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine is used to handle downloading an executionOptions structure for use by the
; ExecuteDTM routine. This is usually performed when the user is also downloading a
; test and subtest combo to be executed as a DTM. However, the user has the option of
; just asking the STM to make a GI_GetDefaultExecutionOptions call if there is nothing
; special needed. The downloaded structure is placed into the executionOptions section
; of the USTGlobals, which has been allocated from the stack (see the USTInit routine).
;
; Inputs: a5 must already be pointing to the USTGlobals
;
; Also, the stack needs to be setup as shown, with the size of the
; executionOptions structure to be downloaded. The reason for requiring the
; size parameter is that it helps insulate STM from CTE-specific knowledge,
; such as the size of data structures, etc. This is good because if anything
; changes about CTE, then the STM needs to know as little as possible. Since
; the user/host is working with CTE, it is not unreasonable to expect the user
; to have this information and supply it to the STM.
;
; While this is a noble cause (separation of STM and CTE), it has not been done
; consistently throughout the ROM yet. Please be patient. Remember that old
; phrase, "Reorg early and reorg often"...or was that "vote early and vote
; often"? Anyway, remember that old phrase.
;
StackFrame8 RECORD 0, Increment ; starts at offset 0 into the stack
@return ds.l 1 ; return address
@globs ds.l 1 ; CTE Global pointer (not used by this routine)
@Size ds.l 1 ; size of the executionOptions structure (in bytes)
ENDR
;
; Outputs: None. If the user gives a bogus address for the info or something else
; goes wrong, it's tough doo doo.
;
;----------------------------------------------------------------------
WITH StackFrame8, USTGlobals
move.l @size(sp),d1 ; get the size of the structure
pea exOpUserInfo(a5) ; put the destination struct pointer on the stack <H8><SM4>
move.l d1,-(sp) ; put the size on the stack
bsr GetCmdData ; and receive the execution options structure
move.l (sp)+,d1 ; get the size back <H8><SM4>
move.l (sp)+,d0 ; and the pointer (to be reported to the user) <H8><SM4>
ENDWITH
rts
; End of UTEDownloadExecutionOptions
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEDownloadExecutionResults
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine is used to handle downloading an executionResults structure for use by the
; ExecuteDTM routine. This is usually performed when the user is also downloading a
; test and subtest combo to be executed as a DTM. However, the user has the option of
; not specifying an execution results structure, in which case the stock exec. results
; structure that is allocated in the USTGlobals will be used (see the USTInit routine).
; The downloaded structure is placed into the executionResults section of the USTGlobals.
;
; Inputs: a5 must already be pointing to the USTGlobals
;
; Also, the stack needs to be setup as shown, with the size of the
; executionResults structure to be downloaded. The reason for requiring the
; size parameter is that it helps insulate STM from CTE-specific knowledge,
; such as the size of data structures, etc. This is good because if anything
; changes about CTE, then the STM needs to know as little as possible. Since
; the user/host is working with CTE, it is not unreasonable to expect the user
; to have this information and supply it to the STM.
;
StackFrame9 RECORD 0, Increment ; starts at offset 0 into the stack
@return ds.l 1 ; return address
@globs ds.l 1 ; CTE Global pointer (not used by this routine)
@Size ds.l 1 ; size of the executionOptions structure (in bytes)
ENDR
;
; Outputs: None. If the user gives a bogus address for the info or something else
; goes wrong, it's tough tomatoes.
;
;----------------------------------------------------------------------
WITH StackFrame9, USTGlobals
move.l @size(sp),d1 ; get the size of the structure
pea exResErr(a5) ; put the destination struct pointer on the stack <H8><SM4>
move.l d1,-(sp) ; put the size on the stack
bsr GetCmdData ; and receive the execution results structure
move.l (sp)+,d1 ; get the size back <H8><SM4>
move.l (sp)+,d0 ; and the pointer (to be reported to the user) <H8><SM4>
ENDWITH
rts
; End of UTEDownloadExecutionResults
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEReturnTestInfo
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine returns all of the information available to this ROM about a ROM-based
; test. The caller passes a pointer to some memory, and it will be filled in with
; information in the following format:
;
; DS.L Test_ID ; ID for this test
; DS.L EntryPtr ; pointer to the entry point
; DS.L NamePtr ; pointer to the name of this test
; DS.L CodeSize ; size of the code (in bytes)
; DS.L ParamSize ; size of the parameter block
; DS.L ResultSize ; size of the results block
;
; Yes, filling in the test ID is probably redundant, but it saves the caller that much
; sweat...
;
; One possible use for this routine would be to get the address so that a breakpoint
; could be set on an emulator.
;
; Another use would be to get a pointer to the name, and download the name using that
; address (the name strings are in "pcString" format, i.e., they're pascal strings with
; terminating nulls).
;
; Inputs:
StackFrame10 RECORD 0, Increment ; starts at offset 0 into the stack
@savedReg ds.l 1 ; place to hold the saved value for the link <H8><SM4>
@return ds.l 1 ; return address is first
@CTEGlobs ds.l 1 ; CTE globals pointer is next
@testID ds.l 1 ; the ID of a ROM-based test
ENDR
;
; NOTE: We must leave a3 and d3 alone for the SendData call. <H11><SM4>
;----------------------------------------------------------------------
@savedRegs reg a0-a5/d1-d5
link a6,#0 ; create a stack frame pointer <H8><SM4>
movem.l @savedRegs,-(sp) ; save these during this operation
WITH StackFrame10, USTTest
move.l @testID(a6),d5 ; <H8><SM4>
; Search the USTTests list of all the ROM-based tests in this ROM (this routine
; will return the address of a Test even if it doesn't apply to this machine,
; just in case someone wants to try stepping through it for some reason). If it
; isn't found, then return -1:
movea.l @CTEGlobs,a0 ; save these for the UTEDumpRAM call
BigLea USTTests,a2 ; get the Test list address
move.l a2,d1 ; and save it for later
@searchLoop
cmp.l #-1,TTest_ID(a2) ; is this the end of the list?
beq.s @Error ; yup, so bail out
cmp.l TTest_ID(a2),d5 ; is this the test we want?
beq.s @foundTest ; yup, so start getting the info
adda.l #sizeofUSTTest,a2 ; nope, so keep looking
bra.s @searchLoop
@foundTest
; Since I know the test info is available at this point, I'll set up some space on
; the stack, fill it in, and setup for the UTEDumpRAM routine, which will send
; it across the serial port to the host:
link a5,#-sizeofUSTTest ; save this much space on the stack for myself
move.l sp,a1 ; the source address for the SendData call <H11><SM4>
move.l TTest_ID(a2),testIDSizeLoc(a5) ; fill in the testID <H11><SM4>
move.l TEntryPtr(a2),a4 ; get the relative entry point <H11><SM4>
add.l d1,a4 ; make it absolute <H11><SM4>
move.l a4,testAddrLoc(a5) ; and store it in its place <H11><SM4>
move.l TNamePtr(a2),a4 ; get the relative ptr to the name string <H11><SM4>
add.l d1,a4 ; make it absolute <H11><SM4>
move.l a4,namePtrLoc(a5) ; and store it in the stack <H11><SM4>
move.l TCodeSize(a2),codeSizeLoc(a5) ; fill in the code size <H11><SM4>
move.l TParamSize(a2),paramSizeLoc(a5) ; and the parameter block size <H11><SM4>
move.l TResultSize(a2),resultSizeLoc(a5) ; and finally, the result block size <H11><SM4>
; Now, prepare the stack for a call to SendData and do it:
movem.l a2/a6,-(sp) ; preserve this across the call <H8><H11><SM4>
move.l a1,-(sp) ; the start address of the data to transfer <H11><SM4>
move.l #sizeofUSTTest,-(sp) ; size of the transfer
bsr SendData ; transmit the data <H11><SM4>
lea 8(sp),sp ; pop the data off the stack <H11><SM4>
movem.l (sp)+,a2/a6 ; restore the USTTests pointer and stack frame ptr <H8><H11><SM4>
unlk a5 ; clean up the stack from the link
@End
moveq.l #0,d0 ; return zero (indicating success) or -1 <H11><SM4>
; (indicating that this test is not <H11><SM4>
; available on this machine)
@Error ; <H11><SM4>
movem.l (sp)+,@savedRegs ; restore them registers
unlk a6 ; clean it up and go home <H8><SM4>
ENDWITH
rts
; End of UTEReturnTestInfo
;----------------------------------------------------------------------
;----------------------------------------------------------------------
UTEReturnSubtestInfo
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine returns all of the information available to this ROM about a ROM-based
; subtest. The caller passes a pointer to some memory, and it will be filled in with
; information in the following format:
;
; DS.L Subtest_ID ; ID for this subtest
; DS.L EntryPtr ; pointer to the entry point
; DS.L NamePtr ; pointer to the name of this subtest
; DS.L CodeSize ; size of the code
; DS.L ParamSize ; size of the parameter block
; DS.L ResultSize ; size of the results block
;
; Yes, filling in the subtest ID is probably redundant, but it saves the caller that much
; sweat...
;
; One possible use for this routine would be to get the address so that a breakpoint
; could be set on an emulator.
;
; Another use would be to get a pointer to the name, and download the name using that
; address (the name strings are in "pcString" format, i.e., they're pascal strings with
; terminating nulls).
;
; Inputs:
StackFrame11 RECORD 0, Increment ; starts at offset 0 into the stack
@savedReg ds.l 1 ; place to hold the saved value for the link <H8><SM4>
@return ds.l 1 ; return address is first
@CTEGlobs ds.l 1 ; CTE globals pointer is next
@subtestID ds.l 1 ; the ID of a ROM-based subtest
ENDR
;
; NOTE: We must leave a3 and d3 alone for the SendData call. <H11><SM4>
;----------------------------------------------------------------------
@savedRegs reg a0-a5/d1-d5
link a6,#0 ; create a stack frame pointer <H8><SM4>
movem.l @savedRegs,-(sp) ; save these during this operation
WITH StackFrame11, USTSubtest
move.l @subtestID(a6),d5 ; <H8><SM4>
; Search the USTTests list of all the ROM-based tests in this ROM (this routine
; will return the address of a Test even if it doesn't apply to this machine,
; just in case someone wants to try stepping through it for some reason). If it
; isn't found, then return -1:
movea.l @CTEGlobs(a6),a0 ; save these for the UTEDumpRAM call
BigLea USTSubtests,a2 ; get the Subtest list address
move.l a2,d1 ; and save it for later
@searchLoop
cmp.l #-1,STSubtest_ID(a2) ; is this the end of the list?
beq.s @Error ; yup, so bail out <H11><SM4>
cmp.l STSubtest_ID(a2),d5 ; is this the test we want?
beq.s @foundSubtest ; yup, so start getting the info
adda.l #sizeofUSTSubtest,a2 ; nope, so keep looking
bra.s @searchLoop
@foundSubtest
; Since I know the test info is available at this point, I'll set up some space on
; the stack, fill it in, and setup for the UTEDumpRAM routine, which will send
; it across the serial port to the host:
link a5,#-sizeofUSTSubtest ; save this much stack space for myself
move.l sp,a1 ; the source address for the SendData call <H11><SM4>
move.l STSubtest_ID(a2),testIDSizeLoc(a5) ; fill in the subtestID <H11><SM4>
move.l STEntryPtr(a2),a4 ; get the relative entry point <H11><SM4>
add.l d1,a4 ; make it absolute <H11><SM4>
move.l a4,testAddrLoc(a5) ; and store it in its place <H11><SM4>
move.l STNamePtr(a2),a4 ; get the relative ptr to the name string <H11><SM4>
add.l d1,a4 ; make it absolute <H11><SM4>
move.l a4,namePtrLoc(a5) ; and store it in the stack <H11><SM4>
move.l STCodeSize(a2),codeSizeLoc(a5) ; fill in the code size <H11><SM4>
move.l STParamSize(a2),paramSizeLoc(a5) ; and the parameter block size <H11><SM4>
move.l STResultSize(a2),resultSizeLoc(a5) ; and finally, the result block size <H11><SM4>
; Now, prepare the stack for a call to SendData and do it:
movem.l a2/a6,-(sp) ; preserve this across the call <H8><H11><SM4>
move.l a1,-(sp) ; the start address of the data to transfer <H11><SM4>
move.l #sizeofUSTSubtest,-(sp) ; size of the transfer
bsr SendData ; transmit the data <H11><SM4>
lea 8(sp),sp ; pop the data off the stack <H11><SM4>
movem.l (sp)+,a2/a6 ; restore the USTTests pointer and stack frame ptr <H8><H11><SM4>
unlk a5 ; clean up the stack from the link
@End
moveq.l #0,d0 ; return zero (indicating success) or -1 <H11><SM4>
; (indicating that this test is not <H11><SM4>
; available on this machine)
@Error ; <H11><SM4>
movem.l (sp)+,@savedRegs ; restore them registers
unlk a6 ; clean it up and go home <H8><SM4>
ENDWITH
rts
; End of UTEReturnSubtestInfo
;----------------------------------------------------------------------
;----------------------------------------------------------------------
GetCmdData
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This routine gets a certain number of characters from the serial port
; using the register based routine GetChar. Data is returned to a place in
; RAM pointed to by a0. The number of characters to get is in d0. If the ASKI bit
; in d7 is set, the data will be converted from ASCII to binary upon input.
;
; Inputs:
StackFrame12 RECORD 0, Increment ;Starts at offset 0 into the stack
@return ds.l 1 ;Return address
@byteCnt ds.l 1 ;byte count to receive
@outputPtr ds.l 1 ;place to put the received data
ENDR
;
; and the following registers:
;
; a3 - SCC read base addr
; d3 - SCC write offset from base
;
; Output:
; (a0) - holds the retrieved data
;
; Destroyed:
;
; Called by: bsr
;
;----------------------------------------------------------------------
WITH StackFrame12
move.l @byteCnt(sp),d1 ;get the byte count
btst.l #aski,d7 ;is this binary we're receiveing?
beq.s @binary ;branch if we're in binary mode
lsl.l #1,d1 ;else, adjust for ascii
@binary
movea.l @outputPtr(sp),a0 ;get the output buffer pointer
@nextChar
movem.l a0/a5/d1,-(sp) ;save our local copies
@wait
BSR6 GetChar ;see if there's a char waiting
tst.w d0 ;do we have one?
bmi.s @wait ;keep waiting if not
btst.l #echo,d7 ;are we supposed to be echoing?
beq.s @noEcho ;continue if not
move.l d0,d1 ;else, save d0
BSR6 OutChar ;and send out the char
move.l d1,d0 ;then restore the value
@noEcho
btst.l #aski,d7 ;binary or ascii?
beq.s @noConversion ;branch if already in binary
cmp.b #'a',d0 ;is this an upper case letter?
blt.s @notUpper ;branch if not
and.b #~('a'--'A'),d0 ;else, fold this to upper case
@notUpper
BSR6 CvtAscii ;and convert it to binary
movem.l (sp)+,a0/a5/d1 ;restore our regs
btst.l #0,d1 ;is this an even nibble or odd?
bne.s @odd ;branch if odd
lsl.b #4,d0 ;else, move it to the high nibble
move.b d0,(a0) ;and store it in RAM for latter
bra.s @Continue ;then continue
@odd
or.b d0,(a0)+ ;OK, or in the low nibble and increment
bra.s @Continue ;then continue
@noConversion
movem.l (sp)+,a0/a5/d1 ;restore our regs
move.b d0,(a0)+ ;store the next byte into the receiving area
@Continue
subq.l #1,d1 ;decrement the count
bgt.s @nextChar ;and continue if necessary
ENDWITH
rts
SendData
;----------------------------------------------------------------------
;
; This routine sends numeric data to the serial port using the register
; based routine OutChar. This routine takes a pointer to data and sends it,
; byte for byte to the serial port. If the ASCII mode option is selected, this
; routine first translates the data into ASCII before sending it.
;
; Inputs:
StackFrame13 RECORD 0, Increment ;Starts at offset 0 into the stack
@return ds.l 1 ;Return address
@byteCnt ds.l 1 ;byte count to send
@outputPtr ds.l 1 ;pointer to data to send
ENDR
;
; and the following registers:
;
; a3 - SCC read base addr
; d3 - SCC write offset from base
;
; Output:
;
; Destroyed:
; a0, d0, d1, d2
;
; Called by: bsr
;
;----------------------------------------------------------------------
WITH StackFrame13
bsr @crlf ;start out with a <CR><LF>
move.l @byteCnt(sp),d1 ;get the byte count
move.l d1,d4 ;save it for later
movea.l @outputPtr(sp),a0 ;and the output buffer pointer
@nextChar
move.b (a0)+,d0 ;get the next byte to send
btst.l #aski,d7 ;is this ascii mode?
beq.s @notASCII ;branch if not
move.b d0,d2 ;save it for later
lsr.b #4,d0 ;get the upper nibble
bsr @CvtBin ;convert to an ASCII char
BSR6 OutChar ;send it out
move.b d2,d0 ;get the next nibble
and.b #$0F,d0 ;mask out the nibble of interest
bsr @CvtBin ;convert it to ASCII
@notASCII
BSR6 OutChar ;send character out
cmp.l #4,d4 ;are we reading less than a long word?
ble.s @notBoundary ;continue if so
move.l a0,d0 ;let's look at this address
and.b #3,d0 ;are we at a long word boundary?
bne.s @notBoundary ;continue if not
bsr @crlf ;else, send a <CR><LF>
@notBoundary
subq.l #1,d1 ;subtract one from the count
bgt.s @nextChar ;and continue if more to go
ENDWITH
moveq.l #0,d0 ;clear return status
rts
@CvtBin
cmp.b #$0A,d0 ;is this going to be a letter or number?
blt.s @number ;branch if number
add.b #('A'-$A),d0 ;else, convert to a letter
bra.s @rtn ;and return
@number
add.b #'0',d0 ;convert to an ASCII number
@rtn
rts ;and return
@crlf
move.b #cr,d0 ;send a crlf
BSR6 OutChar
move.b #lf,d0
BSR6 OutChar
rts
; End of SendData
;----------------------------------------------------------------------
;----------------------------------------------------------------------
; From here to the next <T6> below was added from USTTestMgr.a.
;The original code has been modified so that it leverages off of the CTE tables I
;added to the serial test manager, all the support code for which is located in this
;file, hence the move. Scott Smyers
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
;
; This entry point is called as a subroutine from the diagnostic ROMs. It is safe to <H4><SM4>
; assume that there are at least 256 bytes of valid memory (established by the board <H4><H7><SM4>
; tester before coming here), so using stack-based activities is OK. <H4><SM4>
;
; For all commands but the initialization request and the critical memory tests, the <H4><SM4>
; value in a5 must be preserved between calls. <H4><SM4>
;
; For the Horror ROM, there are basically six things that can be done by this <H4><SM4>
; routine: <H4><SM4>
; - init the interface
; - execute any of the CTE Generic Interface calls
; - execute a DTM
; (this ability is provided as a convenience to the board tester
; because it will not have access to the required information
; to make the GI_ExecuteDTM call for ROM-based DTMS - this is
; by design)
; - read PRAM
; - write PRAM
; - execute a critical test (these are NOT DTMs, but stand alone tests)
;
; IMPORTANT NOTE: In order to maintain the connection with the board testers across
; the memory tests (which wipe out everything), the board testers will save their
; critical information in PRAM before requesting a critical test. After executing
; a critical test, I need to restore their information from PRAM. They will save
; their info in the following format:
;
; D0 - D5, D7
; A0 - A2, A4 - A7
;
; These registers will have been stored in PRAM in the following locations:
;
; $10 - $48
;
; Therefore, I need to restore them appropriately. However, since reading from PRAM
; uses a lot of registers, I will use the first chunk of RAM and read the bytes
; from PRAM ($10 - $48) into RAM. Then, I will stuff the values in RAM into the
; appropriate registers, and jump back to the board tester.
;
; --- New comments added from this <H7> to the one below: ---
;
; There is a special case where I need to store a couple of values into PRAM myself.
; When the IHT is requesting initialization (D7 = 0), I will end up wiping out the
; stack and registers. The IHT will need to store its data as it would if it were
; requesting a critical test (in the format above), but I will pull the return
; address off the stack when I get control and stuff it into PRAM where A6 is stored
; by the IHT. In addition, after doing the USTInit routine and before restoring
; the registers, I will store the new value of A5 (my USTGlobals pointer) into
; PRAM where the IHT would store A5. Finally, I need to store the new A7 (after USTInit)
; in PRAM where it would be. That way, when I go to the routine that restores
; the registers, A5, A6 and A7 will be set appropriately.
;
; --- New comments added from this <H7> to the one above. ---
;
; For all commands except the initialization request, the stack must be set up by
; the caller (board tester). This is done by invoking one of the board tester-specific
; macros in the file IHTROMHook.i. These macros take care of preparing the stack
; and setting D7 to the correct selector value.
;
;
; Input:
; d7.l $00000000 - initialize the interface and CTE (must be first call)
;
; $0000yyyy - execute a utility call where yyyy is the following:
; 0001 - DiagExecuteDTM - the test & subtest IDs are on the stack
; 0002 - Read PRAM
; 0003 - Write PRAM
;
; $0001yyyy - execute any Generic Interface call where yyyy is the following:
; 0000 - GI_InitInterface
; 0001 - GI_GetVersion
; 0002 - GI_AllocPermMem
; 0003 - GI_AllocTempMem
; 0004 - GI_FreeTempMem
; 0005 - GI_GetCommentary
; 0006 - GI_GetDefaultExecutionOptions
; 0007 - GI_ExecuteDTM
;
; $0002yyyy - execute a critical test where yyyy is the following:
; 0000 - SizeMemory
; 0001 - DataBusTest
; 0002 - Mod3Test
; 0003 - Address Line
; 0004 - ROM Byte Lane Checksum
; 0005 - RevMod3Test
; 0006 - ExtRAMTest
;
; Output:
; d6.l The DTM error code returned from the requested operation or from the
; ExecuteDTM routine (depending on what was done).
;
; a3.l The address of this entry point for the IHT to use to get back here.
;
;-----------------------------------------------------------------------------
diagROMentry
IHTCritCodeBase equ $20000 ; base number for IHT critical routines <H7><SM4>
A5PRAMLocation equ $3c ; where A5 will be stored in PRAM <H7><SM4>
A6PRAMLocation equ $40 ; where A6 will be stored in PRAM <H7><SM4>
A7PRAMLocation equ $44 ; where A7 will be stored in PRAM
NumPRAMBytes equ $38 ; this is how many bytes the IHT will save <H7><SM4>
; in PRAM, and how many I should restore <H7><SM4>
RAMDestination equ $10 ; PRAM will be read into this location of RAM <H7><SM4>
PRAMSource equ $10 ; the IHT will store data in PRAM here <H7><SM4>
; Check first to see if this is an initialization request (d7 = 0):
tst.l d7 ; see what's requested
bne.w @notInit ; branch if this is not an init request <H7><SM4>
WITH USTGlobals
; Save the return address in PRAM where the IHT would have saved A6 for a critical test: <H7><SM4>
moveq.l #0,d2 ; <H7><SM4>
BigBSR6 JGetHardwareInfo,a0 ; get hardware info about this machine <H7><SM4>
movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer <H7><SM4>
move.l sp,a6 ; retrieve the return address to the board tester <H7><SM4>
move.w #A6PRAMLocation,a3 ; get the destination PRAM address <H7><SM4>
move.w #4,a5 ; number of bytes to write (decimal) <H7><SM4>
_CopyRAMToPRAM (a6), a3, a5 ; write the return address to PRAM <H7><SM4>
nop ; this is used to separate the macro above <H7><SM4>
; from the one below, for the assembler <H7><SM4>
; Do the real initialization stuff: <H7><SM4>
moveq #0,D2 ; Tell USTInit to call SizeMem <SM5>
BigBSR6 USTInit,a0 ; Initialize the universal environment <H7><SM4>
move.w #RunBits.STM,RunMode(a5) ; set the run mode for serial test manager <H7><SM4>
suba.l #SizeOfCTEGlobals,sp ; allocate our CTE global area on the stack <H7><SM4>
move.l sp,CTEGlobals(a5) ; save the global area pointer <H7><SM4>
movea.l CTEGlobals(a5),a0 ; get the globs pointer <H7><SM4>
CASE ON
GIM_InitInterface (a0),#SIZEOFCTEGLOBALS ;init the CTE interface <T7>
CASE OFF
; Now save the resulting A5 and A7 values into PRAM before jumping to the @CritExit routine <H7><SM4>
; I know this is ugly, but I have to do two separate write requests because A5 and A7 are <H7><SM4>
; not contiguous in PRAM. <H7><SM4>
move.l a5,-(sp) ; put A5 into RAM for CopyRAMToPRAM <H7><SM4>
moveq.l #0,d2 ; <H7><SM4>
BigBSR6 JGetHardwareInfo,a0 ; get hardware info about this machine <H7><SM4>
movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer <H7><SM4>
move.l sp,a6 ; get the RAM source address <H7><SM4>
move.w #A5PRAMLocation,a3 ; get the PRAM destination address <H7><SM4>
move.w #4,a5 ; the number of bytes to write <H7><SM4>
_CopyRAMToPRAM (a6), a3, a5 ; write the USTGlobals address to PRAM <H7><SM4>
lea 4(sp),sp ; clean up the stack <H7><SM4>
move.l sp,-(sp) ; put A7 into RAM for CopyRAMToPRAM <H7><SM4>
moveq.l #0,d2 ; <H7><SM4>
BigBSR6 JGetHardwareInfo,a0 ; get hardware info about this machine <H7><SM4>
movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer <H7><SM4>
move.l sp,a6 ; get the RAM source address <H7><SM4>
move.w #A7PRAMLocation,a3 ; get the PRAM destination address <H7><SM4>
move.w #4,a5 ; the number of bytes to write <H7><SM4>
_CopyRAMToPRAM (a6), a3, a5 ; write the new sp address to PRAM <H7><SM4>
lea 4(sp),sp ; clean up the stack <H7><SM4>
ENDWITH
bra.l @CritExit ; return to the board tester <H7><SM4>
; From here to the <H4> below was modified to support access to the critical tests in
; ROM by the IHT.
;_______________________________________________________________
@notInit
; It's not an init request, so check to see if it's a critical test request:
movea.l sp,a4 ; preserve the return address to board testers
; (none of the critical tests modify a4)
move.l d7,d4 ; get a copy of the operation request
and.l #$000F0000,d4 ; mask out the "code type" value
cmp.l #IHTCritCodeBase,d4 ; see if it's a $xxx2xxxx function (critical test)
bne.l @OtherRequest ; nope, so it's probably a GI_xxx or Utility request
; OK, do the critical test as required. Since I'm responsible for doing the setup
; before testing memory (sizing, determining which bank(s) to test, etc.), I need
; to retain some amount of control in between test cycles. Since I want to use the
; TJump table, I'll have to do a little work in some circumstances (specifically,
; for the RAM tests - MOD3, RevMOD3, ExtRAMTest). So, the first thing I need to do
; is jump to the appropriate setup routine, based on the operation requested (Mod3,
; SizeMemory, etc.). Note that some of the tests (ROM checksum, Address Line Test)
; don't require any setup:
move.l d7,d4 ; get a copy of the operation request
and.l #$000000FF,d4 ; isolate the test number, prepare for setup entry
lea @DiagCritSetup,a5 ; get the critical test setup table
lsl.w #2,d4 ; adjust the offset
move.l (a5,d4.w),d4 ; get the jump table entry
jmp (a5,d4.w) ; and dispatch to proper point
nop ; these are here in case the proper point happens
nop ; to be the entry point below (@theSizeMemTest)
nop
nop
;_______________________________________________________________
;
;---- Do the SizeMem test:
;
@theSizeMemTest
BigBSR6 SizeMemory,a0 ; do the test
bra.l @critExit ; now restore the IHT (error result is in d6)
; and return to it
;_______________________________________________________________
;
;---- Do the ExtRAMTest, Mod3Test or the RevMod3Test - NOTE: it is best to test memory one
; bank at a time with these tests, so that's how I'll be doing it. Since I need to
; retain control to test each memory bank, I will set the return address back to me
; until all banks have been tested. After the test, or if any errors occur during a
; test, I will return to the diagnostic ROM with the results.
;
@theRAMTests
moveq.l #0,d0 ; this is the index into the memory chunk table
; For each bank of memory, do a SizeMem to get the range of addresses for the tests,
; then test that bank. Keep looping until all banks have been tested:
lsl.w #8,d7 ; save the test number in the high byte of the
; low word of d7
move.b d0,d7 ; preserve d0 across SizeMemory - d7 is the only
; register that remains unmolested by SizeMemory
@testAChunkOMemory ; branch back to here on subsequent loops, with the test
; number and d0 still preserved from making the call
; to the requested test <6><Apollo>
BigBSR6 SizeMemory,a0 ; on return, (sp) points to memory table
tst.l d6 ; check for an error
bne.l @critExit ; error, exit to board testers
movea.l (sp),a2 ; otherwise, get pointer to memory table
; Now, test the next bank of memory with the selected test:
move.l #0,d0 ; restore d0 after the SizeMemory call <6><Apollo>
move.b d7,d0 ; restore my running memory table index <6><Apollo>
lsr.w #8,d7 ; get access to the test number <6><Apollo>
movea.l (a2,d0.w),a0 ; get address of the next chunk in the memory table
cmpa.l #$FFFFFFFF,a0 ; check it for the termination value
beq.l @critExit ; end of the Mod3Tests if end of memory table
movea.l (a2,d0.w),a1 ; otherwise, prepare to get terminating address for test
add.w #4,d0 ; get the length of the next chunk in the table
adda.l (a2,d0.w),a1 ; add chunk length to the address, to get end of chunk
lea TJump,a5 ; point to test jump table
adda.l (a5,d7.w * 4),a5 ; point to test
lsl.w #8,d7 ; save the test number in the high byte of the <6><Apollo>
; low word of d7
move.b d0,d7 ; preserve d0 across the RAM tests - d7.lw is the only <6><Apollo>
; data register that remains untouched by the
; mod3 tests IF AND ONLY IF d7.hw = 0, because of
; code that was added for parity but not documented.
lea @1, a6 ; setup return address <SM4>
jmp (a5) ; execute requested test <6><Apollo><SM4>
@1 ; <SM4>
tst.l d6 ; see if there is an error returned <6><Apollo>
bne.l @critExit ; quit the test if so <6><Apollo>
addq.b #4,d7 ; increment the mem table index to point to the <6><Apollo>
; next chunk o' memory <6><Apollo>
bra.s @testAChunkOMemory ; and go test it
;_______________________________________________________________
;
;---- Do the Data Bus Test:
;
@theDataBusTest
; Start by doing a SizeMem to get the range of addresses for the Data Bus Test:
BigBSR6 SizeMemory,a0 ; on return, (sp) points to memory table
tst.l d6 ; check for an error
bne @critExit ; error, exit to board testers
movea.l (sp),a0 ; otherwise, get pointer to memory table
; for the Data Bus Test
; Now do the DataBus test:
If Not forRomulator Then
BigBSR6 DataBusTest,a1 ; do the test and return here (d6 will be set)
Endif
bra.l @critExit ; done with this critical test, so restore the
; state of the IHT and go back to it
;_______________________________________________________________
;
;---- Do the Address Line or ROM Checksum Tests. These don't require any setup, but
; I am using the TJump table to gain access, based on the selector in d7:
;
@theOtherTests
; Start by doing a SizeMem to get the range of addresses for the Address Line Test <H12><SM4>
; in case that happens to be the one we're going to execute: <H12><SM4>
BigBSR6 SizeMemory,a0 ; on return, (sp) points to memory table <H12><SM4>
tst.l d6 ; check for an error <H12><SM4>
bne @critExit ; error, exit to board testers <H12><SM4>
movea.l (sp),a0 ; otherwise, get pointer to memory table <H12><SM4>
; for the Data Bus Test <H12><SM4>
lea @critExit,a6 ; the return address after the test is done
lea TJump,a5 ; point to test jump table
and.l #$000000FF,d7 ; isolate the test number
adda.l (a5,d7.w * 4),a5 ; point to test
jmp (a5) ; execute requested test - return address to
; @critExit is in a6
;_______________________________________________________________
;
;---- At this point, a critical test has been completed (it may have failed). The
; result register (d6) will be set by the time control is passed here, so all
; I need to do is restore the IHT registers from PRAM. The way I do this is to
; read the PRAM data into the first few bytes of memory (I know that these bytes
; are OK because the IHT tests them before even coming here for the first time;
; if I'm here now, then I can assume that those bytes of memory are OK). After
; reading the bytes into RAM, I just copy them into the various registers and
; jump back to the board tester. The reason for doing this is that reading and
; writing PRAM uses up registers, so I need to read everything then write the
; final "real" values into the registers before going back. Note that registers
; d6 (test result) and a3 (IHT hook address - diagROMEntry) are not preserved
; in PRAM; they are set by the hook before going back to the IHT:
;
@critExit
; Read the PRAM data into RAM starting at RAM address $10 (and PRAM address $10):
moveq.l #0,d2 ; <H7><SM4>
BigBSR6 JGetHardwareInfo,a0 ; get hardware info about this machine
movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer
movea.l #RAMDestination,a3 ; get the destination RAM address <H7><SM4>
move.w #PRAMSource,a4 ; beginning address of PRAM to use <H7><SM4>
move.w #NumPRAMBytes,a5 ; number of bytes to read <H7><SM4>
_CopyPRAMToRAM a4, (a3), a5 ; go read PRAM
; Now it's time to load the registers with the required data. The only register I
; have left to work with is a3 (all of the others are going to hold the restored
; data), so I need to be clever in how I do this:
movea.l #RAMDestination,a3 ; the RAM destination is the source now <H7><SM4>
movem.l (a3),d0-d5/d7/a0-a2/a4-a7 ; copy the data into the registers in
; one fell swoop
; Finally, restore a3 (the return address to this IHT hook, diagROMEntry), and jump
; back to the IHT. Remember that d6 is already set, and a6 will be loaded with the
; IHT entry point because the IHT saved a6 in PRAM before coming here:
lea diagROMentry,a3 ; in case the IHT wants to come back later <H7><SM4>
jmp (a6) ; return to the diagnostic ROM
;_______________________________________________________________
;_______________________________________________________________
@OtherRequest
; It's not an init request and it's not a critical test request, so check to see
; if it's a GI_xxx or IHT Utility request:
move.l d7,d0 ; get selected function code in d0
lea @DiagROMUtil,a0 ; assume utility function
and.l #$000F0000,d7 ; mask out the "code type" value
cmp.l #GICodeBase,d7 ; is this a GI call? (d7 = $xxx1xxxx)
bne.s @Branch ; continue if not (it's a utility call)
; At this point we're going to ASSUME it's a GI_xxx call:
lea GI_Table,a0 ; else, get the base address of the GI table
sub.l #GICodeBase,d0 ; and adjust the base of the cmd #
@Branch
WITH USTGlobals
move.l (sp)+,CmdNumber(a5) ; save our return address in a secret location
move.l CTEGlobals(a5),-(sp); common to all
lsl.l #2,d0 ; adjust the offset
move.l (a0,d0.l),d0 ; get the jump table entry
jsr (a0,d0.l) ; and dispatch to proper point
addq.l #4,sp ; pop off the CTE globs
move.l d0,d6 ; put the result into the usual result register
movea.l CmdNumber(a5),a0 ; get the return address
lea diagROMentry,a3 ; get the diag ROM entry point again <T7>
jmp (a0) ; and return to caller
ENDWITH
; End of diagROMentry
;
; From here to the <H4> above was modified to support access to the critical tests in
; ROM by the IHT.
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This table (DiagCritSetup) holds relative entry points to critical test setup
; routines. The reason for these is that for some of them I need to setup prior
; to running them (i.e., size memory and do the Mod3 test for each bank of memory,
; etc.). Also, I need to retain control after the test is done so I can restore the
; state of the board tester and get back to it. So, for the various kinds of critical
; tests available, these are the routines that take care of the setup and dispatch.
;
@DiagCritSetup ; <H4><SM4>
dc.l @theSizeMemTest -@DiagCritSetup ; 0 - SizeMemory <H4><SM4>
dc.l @theDataBusTest -@DiagCritSetup ; 1 - DataBusTest <H4><SM4>
dc.l @theRAMTests -@DiagCritSetup ; 2 - Mod3Test <H4><SM4>
dc.l @theOtherTests -@DiagCritSetup ; 3 - Address Line <H4><SM4>
dc.l @theOtherTests -@DiagCritSetup ; 4 - ROM Byte Lane Checksum <H4><SM4>
dc.l @theRAMTests -@DiagCritSetup ; 5 - RevMod3Test <H4><SM4>
dc.l @theRAMTests -@DiagCritSetup ; 6 - ExtRAMTest <H4><SM4>
@DiagCritSetupSize equ (*-@DiagCritSetup)>>2 ; number of entries <H4><SM4>
;----------------------------------------------------------------------
;----------------------------------------------------------------------
;
; This table (DiagROMUtil) holds relative entry points to utility functions used by the
; In House Tester hook (IHT - also known as the board testers or diagnostic ROM), to
; facilitate IHT-specific operations, which include all of the operations described
; in the diagROMEntry description except the execution of the Generic Interface
; routines. Those routines are accessed from the GI_Table. Note that the IHT environment
; shares one routine with the STM environment, which is DiagExecuteDTM. This routine
; takes a test and subtest ID as input, and executes the ROM-based DTM.
;
@DiagROMUtil
dc.l @DiagROMUtil -@DiagROMUtil ; null entry <T7>
dc.l DiagExecuteDTM -@DiagROMUtil ; execute a DTM
dc.l DiagReadPRAM -@DiagROMUtil ; read PRAM
dc.l DiagWritePRAM -@DiagROMUtil ; write PRAM
@DiagUtilSize equ (*-@DiagROMUtil)>>2 ;number of jump table entries
;----------------------------------------------------------------------
DiagExecuteDTM
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;
; This routine executes a DTM, based on the Test ID and the Subtest ID provided on the
; stack by the caller. Note that a5 must already be initialized to point to the
; USTGlobals before this entry point can be called.
;
; The input is the following call stack:
StackFrame14 RECORD 0, Increment ; start at offset 0 into the stack
@savedReg ds.l 1 ; place to hold the saved value for the link
@return ds.l 1 ; return address is first
@CTEGlobs ds.l 1 ; CTE globals pointer is next
; The following information must be placed on the stack by the code in the Diagnostic
; ROM (board testers):
@subTestID ds.l 1 ; ROM-based subtest ID
@testID ds.l 1 ; ROM-based test ID
ENDR
;
;----------------------------------------------------------------------------
WITH StackFrame14, USTGlobals
link a6,#0 ; save the stack frame pointer
; Since I can use a BSR6 to RAM-lessly jump to a common subroutine that will find
; and execute a DTM combination, the only thing I need to do here is pick the
; test and subtest IDs off of the stack and stuff them into a couple of unused
; registers for the subroutine to use. When it's done, it can RTS6 back to this
; point:
move.l @subTestID(a6),d4
move.l @testID(a6),d5
move.l a6,-(sp) ; save my a6 because the BSR6 uses it
bsr6 SetupForExecuteDTM ; do a RAM-less bsr to the routine that takes
; care of setting up for the execution of a DTM
move.l (sp),a6 ; restore A6 for parameter access later (leave stack as is) <H7><SM4>
; Check for errors in setting up for the ExecuteDTM and don't try to execute the DTM
; if any were found:
cmp.l #-1,tInfoFunctionEntry(a5) ; -1 in this field means test not found
beq.s @LogError
cmp.l #-1,sInfoFunctionEntry(a5) ; -1 in this field means subtest not found
beq.s @LogError
move.l @CTEGlobs(a6),a3 ; we need this for GIM_ExecuteDTM
CASE ON
GIM_ExecuteDTM (a3), EXOPUSERINFO(a5), TINFOUSERINFO(a5), SINFOUSERINFO(a5), EXRESERR(a5)
CASE OFF
bra.s @End
ENDWITH
@LogError
move.l #-1,d6 ; return -1 indicating that either the test
; or subtest doesn't apply to this machine
@End
movea.l (sp)+,a6 ; restore the stack frame pointer <H7><SM4>
move.l d6,d0 ; The normal way of returning the results of a non-critical
; test (ROM-based subtest in CTE lingo) is through d6.
; However, the diagROMEntry routine expects all of the other
; utility routines (write PRAM, etc.) to return the error
; in d0, which it then moves to d6 before returning to the
; board tester. So, we put d6 into d0 here, and the
; diagROMEntry routine will unwittingly move it back to d6.
unlk a6 ; clean up the stack
rts ; return to caller
; End of DiagExecuteDTM
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
DiagReadPRAM
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;
; This routine reads parameter RAM into an area of RAM. Note that a5 must already
; be initialized before this entry point can be called (this will be the case as long
; as the initialization request has already been done).
;
; The input is the following call stack:
StackFrame15 RECORD 0, Increment ; start at offset 0 into the stack
@savedReg ds.l 1 ; place to hold the saved value for the link
@return ds.l 1 ; return address is first
@CTEGlobs ds.l 1 ; CTE globals pointer is next (not used here)
; The following information must be placed on the stack by the code in the Diagnostic
; ROM:
@numBytes ds.w 1 ; number of bytes to read from PRAM
@destRAMAddr ds.l 1 ; destination RAM address
@startPRAMAddr ds.w 1 ; starting PRAM address to read from
ENDR
;
;----------------------------------------------------------------------------
WITH StackFrame15, USTGlobals
link a6,#0 ; save the stack frame pointer
movea.l DcdrInfPtr(a5),a0 ; get the pointer to the decoder info
movea.l PrdctInfPtr(a5),a1 ; and the product info
movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer
movea.l @destRAMAddr(a6),a3 ; get the destination RAM address
movem.l a6,-(sp) ; save our local stack frame pointer
_CopyPRAMToRAM @startPRAMAddr(a6), (a3), @numBytes(a6) ; go read PRAM
movem.l (sp)+,a6 ; restore our local pointer
unlk a6 ; clean up
ENDWITH
rts ; and return to caller
; End of DiagReadPRAM
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
DiagWritePRAM
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;
; This routine writes parameter RAM from an area of RAM. Note that a5 must already
; be initialized before this entry point can be called.
;
; The input is the following call stack:
StackFrame16 RECORD 0, Increment ; start at offset 0 into the stack
@savedReg ds.l 1 ; place to hold the saved value for the link
@return ds.l 1 ; return address is first
@CTEGlobs ds.l 1 ; CTE globals pointer is next (not used here)
; The following information must be placed on the stack by the code in the Diagnostic
; ROM:
@numBytes ds.w 1 ; number of bytes to write to PRAM
@startPRAMAddr ds.w 1 ; starting PRAM address to write to
@sourceRAMAddr ds.l 1 ; source RAM address
ENDR
;
; NOTE: The BSR6 to ClkWpOff was changed to a BigBSR6 because this file was taken
; out of USTStartTest.a and put into USTStartTest1.a, and the branch became too
; far for a BSR6. HAL 2/12/92
;----------------------------------------------------------------------------
WITH StackFrame16, USTGlobals
link a6,#0 ; save the stack frame pointer
movea.l DcdrInfPtr(a5),a0 ; get the pointer to the decoder info
movea.l PrdctInfPtr(a5),a1 ; and the product info
movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer
movem.l a5/a6,-(sp) ; save some regs
BigBSR6 ClkWpOff,a5 ; turn off the write protect bit
movem.l (sp)+,a5/a6 ; restore regs
movea.l @sourceRAMAddr(a6),a3 ; get the source RAM address
movem.l a6,-(sp) ; save our local stack frame pointer
_CopyRAMToPRAM (a3), @startPRAMAddr(a6), @numBytes(a6) ; go write PRAM
movem.l (sp)+,a6 ; restore our local pointer
unlk a6 ; clean up
ENDWITH
rts
; End of DiagWritePRAM
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
SetupForExecuteDTM
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; Well, here it is. This is that fabled routine that actually does the hard
; work of setting up the parameters expected by GI_ExecuteDTM (TestInfo, SubtestInfo,
; ExecutionOptions and ExecutionResults structures). This routine is used by all
; of the ROM-based diagnostics environments in order to allow the user (whether
; that user is the ROM Burnin chamber or the Board Tester or whatever) to set up for
; the GI_ExecuteDTM routine without knowing anything about the various test/subtest
; tables utilized by the ROM.
;
; Currently, this routine fills in the minimum information necessary in the
; following structures: executionOptions, testInfo and subtestInfo. There is no need
; to fill in the executionResults structure.
;
; Additionally, it fills in the info for a StdTestParams structure (which consists
; of the modifier and machineType fields), which is pointed to by the testParams
; field of the executionOptions structure. So, after filling in the standard test
; params structure, its address is placed in the testParams field of the executionOptions
; structure that is also created here. The data for the standard test params fields
; is included in the tests list in the file USTSubtests.a. As CTE-style tests are
; added to this file, it is the responsibility of the person adding them to make
; sure that all values are kept up to date. One way of doing this might be to export
; references to these values from the appropriate CTE test interface files, and include
; them in the USTSubtests.a file. That way, as things are changed in the CTE interfaces,
; they are automatically updated in the assembly file. Just a thought.
;
;
; Input: d4.l subtest ID
; d5.l test ID
; a5.l points to the UST Globals (and the ROM-CTE globals which
; exist immediately after the UST globals)
; a6.l return address (called by BSR6)
;
;
; Output: The ExecuteDTM parameters (on the stack, at the top of the USTGlobals)
; will be filled out, ready for the macro call GIM_ExecuteDTM to push
; the appropriate addresses on the stack and make the call. The macro
; can be called repeatedly in a loop if necessary, and the error code
; returned can be checked. The input parameters don't have to be filled
; in again until a new DTM is needed.
;
;
; Register
; Usage: a0,a1,a3,d1,d3 - no guarantees on being the same when leaving.
; Specifically, the following happens:
;
; a0,a1 - used mercilessly, then tossed aside like some old shoes
;
; d1,d2,d3 - they suffer the same fate as a0 and a1
;----------------------------------------------------------------------------
WITH USTTest, USTSubtest, USTGlobals, CPUTestList
; Do the necessary setup for calling GIM_ExecuteDTM. This is new for CTE v2.1 and later,
; and differs from Terror in that the structures for testInfo and subtestInfo,
; executionOptions and executionResults, must be initialized (they are parameters to
; the ExecuteDTM call). The old way was just to get the test and subtest IDs from the
; RBIInfo structure and call ExecuteTest.
; Fill in the testInfo structure required as an input to ExecuteDTM. Using the testID
; that was passed to me in d5, I can look through the cpu specific test list and verify
; that this test is valid for this machine in this environment (STM, IHT, etc.). Also,
; I can search the USTTests list and determine the param size, result size and entry
; point for the TEST:
BigLea USTTests,a0 ; get the test list address (NOT cpu DTM list)
move.l a0,d1 ; save it in another register
move.l d5,d3 ; save the test ID for the search loop
; Begin by walking thru the Test list and determine that this test exists in this ROM: <H4><SM4>
@TestSearchLoop
cmp.l TTest_ID(a0),d3 ; is this our test?
beq.s @FoundTest ; branch if so
adda.w #sizeofUSTTest,a0 ; else, go to the next entry
cmp.l #-1,TTest_ID(a0) ; are we at the end?
bne.s @TestSearchLoop ; continue if not
bra.s @LogTestError ; we didn't find the requested test so bail
; OK, it exists. Now, determine if it's OK to run it in this "environment", i.e., startup, <H4><SM4>
; restart, STM, etc. This information can be derived from the CPU-specific test list: <H4><SM4>
@FoundTest
movea.l GlobCPUTestList(a5),a1 ; get the CPU specific test list
@FlagSearchLoop ; <H4><H5><SM4>
cmp.w TLSubTest_ID(a1),d4 ; check the current entry against the requested subtest ID <H4><SM4>
beq.s @CheckFlags ; OK, we've found the correct entry, so verify the run flags <H4><H5><SM4>
cmp.w #-1,TLSubTest_ID(a1) ; have we exhausted the list? <H4><SM4>
beq.s @LogTestError ; yes, so just indicate "does not apply" <H4><SM4>
adda.l #sizeofCPUTestList,a1 ; index to next DTM entry in CPU-specific list <H4><SM4>
bra.s @FlagSearchLoop ; go back and keep checking <H4><H5><SM4>
@CheckFlags ; <H4><H5><SM4>
move.w TLrunflags(a1),d2 ; get the runmode flag
and.w RunMode(a5),d2 ; is this test OK for this environment?
bne.s @FillInTest ; continue if so
; If we're here, then either the test wasn't found or it doesn't apply to our current <H4><SM4>
; environment. Either way, move -1 into the result register and skip town: <H4><SM4>
@LogTestError
move.l #-1,tInfoFunctionEntry(a5) ; fill in the entry point field of the testInfo
; struct with -1, indicating that this
bra.l @End ; test does not apply to this environment
; (either because it wasn't found or the
; run mode flags say so)
; At this point we've determined that the test does exist AND that it's OK to run it <H4><SM4>
; right now. So, fill in the info structure for it. Also, since it's OK to run this test <H4><SM4>
; at this time, it's also OK to run the subtest, so no need to check on that (just fill <H4><SM4>
; in the subtest info): <H4><SM4>
@FillInTest
movea.l TEntryPtr(a0),a1 ; get the entry point
adda.l d1,a1 ; make the entry point absolute
move.l a1,tInfoFunctionEntry(a5) ; fill in the entry point field of the testInfo struct
move.l d5, tInfoID(a5) ; do the same for the test ID
move.l #0,tInfoUserInfo(a5) ; the rest of the default values for the testInfo
move.l TParamSize(a0),tInfoParamsSize(a5) ; structure may or may not be
move.l TResultSize(a0),tInfoResultsSize(a5) ; NIL, depending on the Test
; Fill in the subtestInfo structure required as an input to ExecuteDTM. Using the subTestID
; that was passed to me in d4, I can search the USTSubTests list and find the entry
; point for the SUBTEST. In addition, I can find the param size and result size
; values from the USTSubtests table:
BigLea USTSubtests,a0 ; get the subtest list
move.l a0,d1 ; save it in another register
move.l d4,d3 ; save the subtest ID for the search loop
@SubtestSearchLoop
cmp.l STSubtest_ID(a0),d3 ; is this our subtest?
beq.s @FoundSubtest ; branch if so
adda.w #sizeofUSTSubtest,a0 ; else, go to the next entry
cmp.l #-1,STSubtest_ID(a0) ; are we at the end?
bne.s @SubtestSearchLoop ; continue if not
move.l #-1,sInfoFunctionEntry(a5) ; fill in the entry point field of the subtestInfo
; struct with -1, indicating that there
bra.s @End ; is something wrong - we didn't find the
; requested subtest
@FoundSubtest
movea.l STEntryPtr(a0),a1 ; get the entry point
adda.l d1,a1 ; make the entry point absolute
move.l a1,sInfoFunctionEntry(a5) ; fill in the entry point field of the subtestInfo struct
move.l d4, sInfoID(a5) ; do the same for the subtest ID
move.l #0,sInfoUserInfo(a5) ; the rest of the default values for the subtestInfo
move.l STParamSize(a0),sInfoParamsSize(a5) ; structure may or may not be
move.l STResultSize(a0),sInfoResultsSize(a5) ; NIL, depending on the Subtest
; If we've made it this far, then all the test/subtest info was found and verified for the
; current environment. So, create the standard test params and execution options. Also,
; set the userInfo field of the executionOptions to point to the USTGlobals and the
; testParams field to point to the standard test params structure. The reason for setting
; the userInfo field to point to the USTGlobals is that the ROM-based non-critical
; tests (the non-CTE ones) all expect the following input register values:
;
; a0 - ptr to table of hardware base addresses (DecoderInfo ptr)
; a1 - ProductInfo ptr
; d0 - bit mask indicating which base addresses are valid (bases valid flags)
; d2 - boxflag/decoder type
;
; The ROM-based CTE-style Test (which is coupled with the non-CTE ROM-based non-
; critical subtests to form DTMs) takes care of setting up the a0, a1, d0 and d2
; registers before jumping into one of those subtests. The other ROM-based CTE style
; DTMs may or may not use the userInfo pointer, based upon their personal preferences.
;
;
; Here's the StdTestParams:
; move.l
; Here's the executionOptions:
move.l a5,exOpUserInfo(a5) ; this puts the USTGlobals pointer into the userInfo
move.l #4,exOpProcessorType(a5)
move.l #0,exOpExecutionMode(a5)
move.l #0,exOpTestParams(a5)
move.l #0,exOpTestResultsOverride(a5)
move.l #0,exOpSubtestParamsOverride(a5)
move.l #0,exOpSubtestResultsOverride(a5)
move.l #0,exOpIdleMethod(a5)
move.l #0,exOpIdleMethodArg(a5)
@End
ENDWITH
RTS6 ; go back to the caller
; End of SetupForExecuteDTM
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;<T6>
ENDPROC