;__________________________________________________________________________________________________ ; ; 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): ; ; 9/13/93 SAM Added a flag to USTInit to tell it not to call SizeMem (again!). ; 11/3/92 rab Roll in Horror changes. Comments Follow: ; 7/27/92 AL Fixed the IHT setup for the Address Line Test, which changed ; when SizeMemory changed (see comments in USTCritTests.a). ; 7/15/92 AL Fixed the UTEReturnTestInfo and UTEReturnSubtestInfo functions ; to work correctly, modified some comments to be more accurate. ; 7/9/92 AL Did some fine tuning of a few routines for STM and the IHT hook. ; 07-07-92 jmp Fixed previous check-in comments. ; 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? ; 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. ;
6/17/92 AL Fixed the UTEExecuteDTM routine to correctly access a couple of ; variables relative to the stack. ;
6/7/92 AL Fixed a minor problem with a couple of

comments that ; weren't separated from the code, which could possibly cause an ; assembly process anomoly. ;

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. ; 9/25/92 RB Changed a BSR6 macro to jump. ; 5/2/92 kc Roll in Horror. Comments follow: ;

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. ;

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 ;

IMPORT RevMod3Test ;

IMPORT RomTest ;

IMPORT StartUpROMTest ;

IMPORT ExtRAMTest ;

IMPORT AddrLineTest ;

IMPORT DataBusTest ;

IMPORT dynamic_bussize_test ;

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 ; EXPORT USTMainTest EXPORT SetupForExecuteDTM EXPORT UTECmd EXPORT diagROMentry ; These equates are used by the UTEReturnTestInfo and UTEReturnSubtestInfo functions. They ; are defined in the OPPOSITE order of the USTTest and USTSubtest structure definitions, ; because they are used to place the USTTest entries on the stack as local variables ; in preparation for the SendData call. Local variables are referenced with negative ; offsets from the stack frame pointer (in this case, it's going to be A5): resultSizeLoc equ -4 ; this many bytes off of A5, for the SendData routine paramSizeLoc equ -8 ; this many bytes off of A5, for the SendData routine codeSizeLoc equ -12 ; this many bytes off of A5, for the SendData routine namePtrLoc equ -16 ; this many bytes off of A5, for the SendData routine testAddrLoc equ -20 ; this many bytes off of A5, for the SendData routine testIDSizeLoc equ -24 ; this many bytes off of A5, for the SendData routine 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 rb jmp (a3) ; and execute the subtest rb @1 ; 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 dc.l UTEWritePRAM -STM_Util ; write an area of PRAM 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: ; ; !<# params> ; ; Where: - (long) Command number (offset into jump table below) ; <# params> - (word) Number of bytes to receive for calling params ; - (longs) Parameters for command, must agree with <# params> ; - (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 BigBSR6 USTInit,a0 ; Initialize the universal environment 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 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 move.w @size(a6),d3 ;get the size _CopyPRAMToRAM a3, (a4), d3 ;go read PRAM 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 ^ ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- 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 @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 ; movem.l @savedRegs,-(sp) ; save these during this operation WITH StackFrame5, USTGlobals move.l @subTestID(a6),d4 ; prepare for the SetupForExecuteDTM call
move.l @testID(a6),d5 ;
move.l a6,-(sp) ; save this across the next call 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 ; 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 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 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 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 move.l (sp)+,d0 ; and the pointer (to be reported to the user) 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 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 move.l (sp)+,d0 ; and the pointer (to be reported to the user) 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 @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. ;---------------------------------------------------------------------- @savedRegs reg a0-a5/d1-d5 link a6,#0 ; create a stack frame pointer movem.l @savedRegs,-(sp) ; save these during this operation WITH StackFrame10, USTTest move.l @testID(a6),d5 ; ; 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 move.l TTest_ID(a2),testIDSizeLoc(a5) ; fill in the testID move.l TEntryPtr(a2),a4 ; get the relative entry point add.l d1,a4 ; make it absolute move.l a4,testAddrLoc(a5) ; and store it in its place move.l TNamePtr(a2),a4 ; get the relative ptr to the name string add.l d1,a4 ; make it absolute move.l a4,namePtrLoc(a5) ; and store it in the stack move.l TCodeSize(a2),codeSizeLoc(a5) ; fill in the code size move.l TParamSize(a2),paramSizeLoc(a5) ; and the parameter block size move.l TResultSize(a2),resultSizeLoc(a5) ; and finally, the result block size ; Now, prepare the stack for a call to SendData and do it: movem.l a2/a6,-(sp) ; preserve this across the call move.l a1,-(sp) ; the start address of the data to transfer move.l #sizeofUSTTest,-(sp) ; size of the transfer bsr SendData ; transmit the data lea 8(sp),sp ; pop the data off the stack movem.l (sp)+,a2/a6 ; restore the USTTests pointer and stack frame ptr unlk a5 ; clean up the stack from the link @End moveq.l #0,d0 ; return zero (indicating success) or -1 ; (indicating that this test is not ; available on this machine) @Error ; movem.l (sp)+,@savedRegs ; restore them registers unlk a6 ; clean it up and go home 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 @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. ;---------------------------------------------------------------------- @savedRegs reg a0-a5/d1-d5 link a6,#0 ; create a stack frame pointer movem.l @savedRegs,-(sp) ; save these during this operation WITH StackFrame11, USTSubtest move.l @subtestID(a6),d5 ; ; 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 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 move.l STSubtest_ID(a2),testIDSizeLoc(a5) ; fill in the subtestID move.l STEntryPtr(a2),a4 ; get the relative entry point add.l d1,a4 ; make it absolute move.l a4,testAddrLoc(a5) ; and store it in its place move.l STNamePtr(a2),a4 ; get the relative ptr to the name string add.l d1,a4 ; make it absolute move.l a4,namePtrLoc(a5) ; and store it in the stack move.l STCodeSize(a2),codeSizeLoc(a5) ; fill in the code size move.l STParamSize(a2),paramSizeLoc(a5) ; and the parameter block size move.l STResultSize(a2),resultSizeLoc(a5) ; and finally, the result block size ; Now, prepare the stack for a call to SendData and do it: movem.l a2/a6,-(sp) ; preserve this across the call move.l a1,-(sp) ; the start address of the data to transfer move.l #sizeofUSTSubtest,-(sp) ; size of the transfer bsr SendData ; transmit the data lea 8(sp),sp ; pop the data off the stack movem.l (sp)+,a2/a6 ; restore the USTTests pointer and stack frame ptr unlk a5 ; clean up the stack from the link @End moveq.l #0,d0 ; return zero (indicating success) or -1 ; (indicating that this test is not ; available on this machine) @Error ; movem.l (sp)+,@savedRegs ; restore them registers unlk a6 ; clean it up and go home 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 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 @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 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

; assume that there are at least 256 bytes of valid memory (established by the board

; tester before coming here), so using stack-based activities is OK.

; ; For all commands but the initialization request and the critical memory tests, the

; value in a5 must be preserved between calls.

; ; For the Horror ROM, there are basically six things that can be done by this

; routine:

; - 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 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 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 A5PRAMLocation equ $3c ; where A5 will be stored in PRAM A6PRAMLocation equ $40 ; where A6 will be stored in PRAM A7PRAMLocation equ $44 ; where A7 will be stored in PRAM NumPRAMBytes equ $38 ; this is how many bytes the IHT will save ; in PRAM, and how many I should restore RAMDestination equ $10 ; PRAM will be read into this location of RAM PRAMSource equ $10 ; the IHT will store data in PRAM here ; 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 WITH USTGlobals ; Save the return address in PRAM where the IHT would have saved A6 for a critical test: moveq.l #0,d2 ; BigBSR6 JGetHardwareInfo,a0 ; get hardware info about this machine movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer move.l sp,a6 ; retrieve the return address to the board tester move.w #A6PRAMLocation,a3 ; get the destination PRAM address move.w #4,a5 ; number of bytes to write (decimal) _CopyRAMToPRAM (a6), a3, a5 ; write the return address to PRAM nop ; this is used to separate the macro above ; from the one below, for the assembler ; Do the real initialization stuff: moveq #0,D2 ; Tell USTInit to call SizeMem BigBSR6 USTInit,a0 ; Initialize the universal environment 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 movea.l CTEGlobals(a5),a0 ; get the globs pointer CASE ON GIM_InitInterface (a0),#SIZEOFCTEGLOBALS ;init the CTE interface CASE OFF ; Now save the resulting A5 and A7 values into PRAM before jumping to the @CritExit routine ; I know this is ugly, but I have to do two separate write requests because A5 and A7 are ; not contiguous in PRAM. move.l a5,-(sp) ; put A5 into RAM for CopyRAMToPRAM moveq.l #0,d2 ; BigBSR6 JGetHardwareInfo,a0 ; get hardware info about this machine movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer move.l sp,a6 ; get the RAM source address move.w #A5PRAMLocation,a3 ; get the PRAM destination address move.w #4,a5 ; the number of bytes to write _CopyRAMToPRAM (a6), a3, a5 ; write the USTGlobals address to PRAM lea 4(sp),sp ; clean up the stack move.l sp,-(sp) ; put A7 into RAM for CopyRAMToPRAM moveq.l #0,d2 ; BigBSR6 JGetHardwareInfo,a0 ; get hardware info about this machine movea.l DecoderInfo.VIA1Addr(a0),a2 ; then get the VIA1 pointer move.l sp,a6 ; get the RAM source address move.w #A7PRAMLocation,a3 ; get the PRAM destination address move.w #4,a5 ; the number of bytes to write _CopyRAMToPRAM (a6), a3, a5 ; write the new sp address to PRAM lea 4(sp),sp ; clean up the stack ENDWITH bra.l @CritExit ; return to the board tester ; From here to the

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> 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> move.b d7,d0 ; restore my running memory table index <6> lsr.w #8,d7 ; get access to the test number <6> 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> ; low word of d7 move.b d0,d7 ; preserve d0 across the RAM tests - d7.lw is the only <6> ; 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 jmp (a5) ; execute requested test <6> @1 ; tst.l d6 ; see if there is an error returned <6> bne.l @critExit ; quit the test if so <6> addq.b #4,d7 ; increment the mem table index to point to the <6> ; next chunk o' memory <6> 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 ; in case that happens to be the one we're going to execute: 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 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 ; 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 move.w #PRAMSource,a4 ; beginning address of PRAM to use move.w #NumPRAMBytes,a5 ; number of bytes to read _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 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 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 jmp (a0) ; and return to caller ENDWITH ; End of diagROMentry ; ; From here to the

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 ;

dc.l @theSizeMemTest -@DiagCritSetup ; 0 - SizeMemory

dc.l @theDataBusTest -@DiagCritSetup ; 1 - DataBusTest

dc.l @theRAMTests -@DiagCritSetup ; 2 - Mod3Test

dc.l @theOtherTests -@DiagCritSetup ; 3 - Address Line

dc.l @theOtherTests -@DiagCritSetup ; 4 - ROM Byte Lane Checksum

dc.l @theRAMTests -@DiagCritSetup ; 5 - RevMod3Test

dc.l @theRAMTests -@DiagCritSetup ; 6 - ExtRAMTest

@DiagCritSetupSize equ (*-@DiagCritSetup)>>2 ; number of entries

;---------------------------------------------------------------------- ;---------------------------------------------------------------------- ; ; 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 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) ; 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 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:

@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,

; restart, STM, etc. This information can be derived from the CPU-specific test list:

@FoundTest movea.l GlobCPUTestList(a5),a1 ; get the CPU specific test list @FlagSearchLoop ;

cmp.w TLSubTest_ID(a1),d4 ; check the current entry against the requested subtest ID

beq.s @CheckFlags ; OK, we've found the correct entry, so verify the run flags

cmp.w #-1,TLSubTest_ID(a1) ; have we exhausted the list?

beq.s @LogTestError ; yes, so just indicate "does not apply"

adda.l #sizeofCPUTestList,a1 ; index to next DTM entry in CPU-specific list

bra.s @FlagSearchLoop ; go back and keep checking

@CheckFlags ;

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

; environment. Either way, move -1 into the result register and skip town:

@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

; right now. So, fill in the info structure for it. Also, since it's OK to run this test

; at this time, it's also OK to run the subtest, so no need to check on that (just fill

; in the subtest info):

@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 ;---------------------------------------------------------------------------- ;---------------------------------------------------------------------------- ; ENDPROC