mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 19:31:02 +00:00
2258 lines
93 KiB
Plaintext
2258 lines
93 KiB
Plaintext
;
|
|
; File: USTStartUp.a
|
|
;
|
|
; Contains: StartTest is the routine which performs the necessary hardware tests to verify
|
|
; everythings ok before we attempt booting. After performing critical tests,
|
|
; it executes a series of non-critical tests whose results are logged to PRAM.
|
|
; The sequence of events performed by StartTest are as follows:
|
|
;
|
|
; 1) Setup exception vectors (at loc 0 for 68000, in ROM on 68020/68030
|
|
; 2) Check for diag ROMs, jump into them if present
|
|
; 3) If we have an IOP SCC, set into bypass mode if present
|
|
; 4) Check for factory loopback, if present, go to PRAM logging routine
|
|
; 5) Checksum the ROMs (d7.w = 01)
|
|
; 6) If on a Normandy decoder, test it unique features
|
|
; 7) Size memory, returning (sp) pointing to memory chunk table (d7.w = 11)
|
|
; 8) Make call to BootBeep, to let user know we're alive
|
|
; 9) Perform data bus test on 1st location in first bank found (d7.w = 0E)
|
|
; 10) See if we might have Parity memory, and flag this
|
|
; 11) If cold boot, test all banks of memory (d7.w = 03-04)
|
|
; 12) Run dynamic bus size test for cpu's ≥ 020 (d7.w = 13)
|
|
; 13) Run non-critical tests
|
|
; a) SCC reg test (d7.w = 84)
|
|
; b) SCC timer test (d7.w = 86)
|
|
; c) SCC loopback test (d7.w = 85)
|
|
; d) VIA test (d7.w = 87)
|
|
; e) SCSI test (d7.w = 88)
|
|
; f) ASC reg test (d7.w = 89)
|
|
; g) RBV test (d7.w = 8b)
|
|
; h) SWIM test (d7.w = 8c)
|
|
; i) FPU test (d7.w = 8d)
|
|
; j) Parity test (d7.w = 8e)
|
|
; k) FMC reg test (d7.w = 8f)
|
|
; l) FMC Cache test (d7.w = 90)
|
|
; m) OSS reg test (d7.w = 91)
|
|
; n) OSS Int test (d7.w = 92)
|
|
; o) RPU test (d7.w = 93)
|
|
; p) V8 VRAM test (d7.w = 97) note: this test performs some necessary hw initialization
|
|
; 14) Return to StartInit
|
|
;
|
|
; Written by: Dave Holzer
|
|
;
|
|
; Copyright: © 1983-1994 by Apple Computer, Inc. All rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM42> 2/6/94 kc Add call to TNTBootBeep.
|
|
; <SM40> 1/28/94 chp Reenable almost all the code that was hacked out for
|
|
; TNT-specific bringup builds. Only the actual calls to BootBeep
|
|
; code remain disabled.
|
|
; <SM39> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
|
; machines.
|
|
; <SM38> 11/17/93 KW forSTP601 read pram B0 to determine if 040 should boot
|
|
; <SM37> 11/10/93 chp Conditional out some code during TNT debugging builds and add a
|
|
; check for PDM-style machines before doing PDM-style PDS resets.
|
|
; <SMG3> 9/22/93 chp Added a NOP in some forRomulator code to avoid an assembler
|
|
; warning.
|
|
; <SM36> 11/7/93 SAM Roll in <MC6> from mc900ftjesus.
|
|
; <MC6> 10/31/93 GMR Added code to reset PDM/CF/CS's PDS card if a ConfigROM exists
|
|
; with a special signature near the end of it.
|
|
; <SM35> 10/15/93 SAM Roll in <MC5> from mc900ftjesus.
|
|
; <MC5> 10/15/93 SAM Added some informative comments to the Emu warmstart code.
|
|
; Also, I no longer set the constant if its already set (Oops).
|
|
; <SM34> 10/12/93 SAM Roll in <MC4> from mc900ftjesus.
|
|
; <MC4> 10/12/93 SAM Changed the Emu warmstart code to use the diagnostic page for a
|
|
; home.
|
|
; <SM33> 10/10/93 SAM Roll in <MC2> and <MC3> from mc900ftjesus.
|
|
; <MC3> 10/10/93 SAM Added a call to NuBusReset for machines with BART. Added
|
|
; jGetExtHardwareInfo. No longer do a ROM checksum if the machine
|
|
; started up with a 68k emulator.
|
|
; <MC2> 9/24/93 SAM Learning to add. Adjusted the emu warmstart location.
|
|
; <SM32> 9/13/93 SAM Changed USTInit to look at a flag to determine if it should call
|
|
; SizeMem (again). Made the default boot case NOT call sizemem
|
|
; more than once. Changed the "has68kemu" path to not call the
|
|
; UST stuff at all because those machines have native diagnostics.
|
|
; <SM31> 8/23/93 SAM Don't whack RAM off ASCBase if it is pointing into ROM.
|
|
; Commented out the parity RAM check. Added some warmstart
|
|
; bootbeep stuff for machines that start up with an emulator.
|
|
; <SM30> 6/28/93 SAM For PDM, added a check after sizemem to call PDM's bootbeep code
|
|
; if we're warm starting (hardware init plays the bootbeep on cold
|
|
; starts).
|
|
; <SM29> 6/14/93 kc Roll in Ludwig (Fix the last checkin).
|
|
; <SM28> 5/21/93 kc Move SizeV8VRAM call to where it was before SM26 so the
|
|
; productinfo registers would be set up. Q950 boots again.
|
|
; <SM27> 5/14/93 joe The moving of the bootbeep call was so that we could (on PDM)
|
|
; play the sound using the framebuffer RAM. Now that we don't
|
|
; need to do that any more, move the call to bootbeep back to
|
|
; where it was.
|
|
; <SM26> 5/6/93 joe Moved BootBeep to happen after SizeMem.
|
|
; <SM25> 5/6/93 SAM Fixed <LW2> roll in. Straightened up some things.
|
|
; <SM24> 4/22/93 joe Enable call to BootBeep code on PDM.
|
|
; <SM23> 4/12/93 rab Put back CheckLoopBack routine that was removed in the last
|
|
; checkin. Q900/950s break on boot without this code.
|
|
; <SM22> 3/31/93 chp Synchronize SuperMario with changes from <LW2>.
|
|
; <LW2> 3/21/93 fau Removed the initial loopback tests (before bootbeep). Moved
|
|
; some of the ASC setup code into BootBeep.a so that it didn't get
|
|
; executed on Cyclone.
|
|
; <SM21> 01-11-93 jmp Updated various BoxFlag names.
|
|
; <SM20> 12/2/92 SWC Removed the call to InitWallyWorld since that's done in
|
|
; PortableCheck.
|
|
; <SM19> 11/3/92 rab Rolled in Horror changes. Added testchk routine from Horror.
|
|
; <SM18> 11/01/92 HY Conditionalize call to InitWallyWorld (PG&E stuff) for LC930.
|
|
; <SM17> 10/25/92 HY Put in support for boxMacLCII boxflag.
|
|
; <SM16> 10/21/92 fau Got rid of the <P8> <SM3> changed that did a Cuda command on
|
|
; Cyclone using an MMCExists test; It was deemed not necessary by
|
|
; gjs and me (since a CudaInit had already been done).
|
|
; <SM15> 10/18/92 CCH Bypass some things for PDM bringup.
|
|
; <SM15> 10/18/92 CCH Bypass some things for PDM bringup.
|
|
; <SM14> 10/12/92 RB (HY) Change ElsieROMBase from $00A00000 to $40A00000 so that LC
|
|
; II will work correctly.
|
|
; <SM13> 9/25/92 RB Added a conditional ROMinRAM to avoid things that cannot work
|
|
; when putting a ROM image in RAM. Changed a few BSR6 macros to
|
|
; jumps.
|
|
; <SM12> 8/20/92 CCH Removed now-obsolete conditional for Cub Card.
|
|
; <SM11> 8/19/92 CSS Update from Reality:
|
|
; <43> 8/18/92 DTY Change the name of BootGlobs to StartGlobals to avoid confusion
|
|
; with BootGlobals, which is used by the boot code in Boot[1-3].a.
|
|
; <SM10> 8/9/92 CCH Skip cold starts on RISC Quadras for now.
|
|
; <SM9> 7/7/92 CSS Roll-in reality changes:
|
|
; Remove references to boxApollo changed to boxClassicII.
|
|
; <SM8> 6/26/92 GS Remove the InitCuda/InitEgret Code from the USTStartUp.a file.
|
|
; This initialization has been moved to the Universal.a file just
|
|
; after the INITVias call. The Cuda Firmware now invokes a
|
|
; SyncAck function that will disable the asynchronous messages
|
|
; sources until the system is initialized enough to respond.
|
|
; <SM7> 6/1/92 kc <gjs> Always enable Keyboard NMI. Removed code to disable.
|
|
; <SM6> 5/26/92 RB Test for an MMC decoder before attempting to talk to Cuda. This
|
|
; crashes non Cuda machines. • This check should be changed later
|
|
; for a real Cuda check.
|
|
; <SM5> 5/22/92 RB Added changes from Pandora, mostly to deal with Cuda.
|
|
; <SM3> 5/2/92 kc Roll in Horror. Comments follow:
|
|
; <H13> 3/10/92 AL Changed the check for startup condition in two places to use the
|
|
; correct equate value (a diagnostics-specific equate, not the
|
|
; WarmStartFlag). The wrong value was being checked and was
|
|
; allowing some tests to be run at startup that shouldn't, which
|
|
; subsequently crashed Quadras.
|
|
; <H12> 3/6/92 AL Moved the routine SetVectorTable to USTTestMgr.a because it was
|
|
; more efficient due to the reorganization of the UST files. The
|
|
; reorg was made necessary by the PROC conditionalization by jmp,
|
|
; because we found out that the UST stuff had outgrown its
|
|
; allocated space in the ROM. Modified the non-critical sequence
|
|
; to use CTE v2.1.
|
|
; <H11> 2/5/92 NV Commented out the code to skip boot beep - now calls bootbeep.
|
|
; <H10> 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.
|
|
; <H9> 1/14/92 SWC Updated boxFlag labels to use shipping product names.
|
|
; <H8> 1/13/92 SWC Modified USTPMGRSendCommand, USTPMgrSendByte, USTPMgrRecvByte to
|
|
; get the low-level PMGR-based PRAM code working correctly.
|
|
; <H7> 12/20/91 JC Temporarily not Accessing VIA or calling Bootbeep on Sonora1 as
|
|
; it does bad things and forcing warmstart
|
|
; <H6> 12/3/91 SWC Use the MSC to turn on SCC clocks in USTPmgrTurnOn since SCC
|
|
; clock control is handled by MSC instead of the PMGR.
|
|
; <H5> 10/23/91 jmp Updating from the Zydeco-TERROR project.
|
|
; <H4> 10/15/91 SWC Moved InitWallyWorld closer to the beginning, since there are
|
|
; some PRAM users that can't otherwise be properly supported.
|
|
; <H3> 8/22/91 SWC Added USTPMgrRecvByte so we can receive replies from the PMGR.
|
|
; Added a call to InitWallyWorld to download code into those PMGR
|
|
; microcontrollers that support it.
|
|
; <H2> 8/8/91 SWC Added in support for new PMGR for DB-Lite. Rewrote
|
|
; USTPmgrTurnOn to use a common send command routine
|
|
; (USTPmgrSendcommand), and export USTPMGRSendCommand so that
|
|
; other routines will have a higer-level interface.
|
|
; <SM3> 3/3/92 PN Add missing semicolon
|
|
; <SM2> 3/2/92 kc Add yet another VBR allignment.
|
|
; <42> 1/23/92 RB Aligned the vbr for Romulator
|
|
; <41> 1/13/92 RB Rolled in Terror version. Cleaned up a record label.
|
|
;
|
|
; ==================== Terror History =====================
|
|
;
|
|
; <14> 6/25/91 CCH Rolled out previous change to have MDU-based machines use second
|
|
; bank of RAM during startup.
|
|
; <13> 4/22/91 ag Exported "USTPMGRSendByte" for use in "econo mode" code.
|
|
; <12> 4/2/91 CCH Rolled in Scott Smyers' changes: Made some ambiguous data
|
|
; structures names more unique/descriptive. Added support for the
|
|
; new word sized subtest IDs. Moved the universal SizeVRAM routine
|
|
; to USTNonCritTsts.a, where it's actually called.
|
|
; <11> 4/1/91 BG In the Eclipse Egret initialization sequence, added a call to
|
|
; SendEgretCmd to DISable power-down messages. This will allow you
|
|
; to turn off your Eclipse with the keyswitch before we start
|
|
; reading in the System file.
|
|
; <10> 3/19/91 BG Removed the 800ms wait loop added in <T7>. The Eclipse RESET
|
|
; problem is going to be handled in HW so this is no longer
|
|
; necessary.
|
|
; <9> 3/13/91 CCH Rolled in RBI changes from Scott Smyers.
|
|
; <8> 2/18/91 djw Rolled in Scott Smyers changes
|
|
; <7> 2/14/91 BG Added an 800ms delay loop to allow Caboose to come out of RESET
|
|
; before we attempt any timed assertions to initialize/synchronize
|
|
; with Caboose.
|
|
; <6> 1/14/91 CCH Rolled in Scott Smyers changes.
|
|
; <5> 12/14/90 HJR Removed non reference NCTest Table. Made set vector table work
|
|
; with reanimator and added support for machine dependent NCTest
|
|
; tables.
|
|
; <4> 12/6/90 CCH Changed the check for whether Egret exists to also check for
|
|
; ClockEgret as well as ADBEgret, since Eclipses have the former
|
|
; and not the latter but still need to do the initialization.
|
|
; <3> 10/25/90 CCH Added support for ReAnimator when forRomulator equate is set.
|
|
; <2> 9/17/90 CCH Added modifications for the 68040.
|
|
; ———————————————————————————————————————————————————————————————————————————————————————
|
|
; Pre-TERROR ROM comments begin here.
|
|
; ———————————————————————————————————————————————————————————————————————————————————————
|
|
; <12> 5/31/90 BA Rolling in changes from Reality. Original comments below.
|
|
; {23} 5/31/90 SS moved the call to egretinit so that the DFAC is initialized
|
|
; before ROM test. It need to be inited before the error tones
|
|
; can be heard.
|
|
; <11> 5/18/90 CV Rolling in changes from mainproj. Original comments below.
|
|
; {22} 5/2/90 SS Added calls to SendEgretCmd to enable keyboard NMI during
|
|
; startup tests (just before boot beep), then disable it just
|
|
; before leaving the startup tests.
|
|
; <10> 4/27/90 CV Rolling in changes from mainproj. Original comments below.
|
|
; {21} 4/24/90 SS Moved the equates for Critical, NonCritical and CritBit into
|
|
; STEqu.a.
|
|
; {20} 4/22/90 JJ Remove support for Elsie VISA1 decoder.
|
|
; {19} 4/19/90 SS Exported ElsieTMVectors. These are needed in the serial test
|
|
; manager for running critical tests on Elsie.
|
|
; <9> 4/11/90 JJ Modify test of BURNIN bit on Erickson and Elsie
|
|
; <8> 4/9/90 JJ Changed code to set BURNIN bit to input state before checking
|
|
; burnin value on Elsie.
|
|
; <7> 4/2/90 CV Rolling in changes from mainproj. Original comments below.
|
|
; {16} 3/30/90 SS Moved the call to SendNOPcmd from after the RAM tests to after
|
|
; the ROM tests but before the boot beep. Also changed the name
|
|
; of this routine to EgretInit. EgretInit turns off tick packets
|
|
; and ADB autopolling and it initializes the DFAC so that the boot
|
|
; beep works on Elsie.
|
|
; {15} 3/27/90 JJ Made burnin jumper test conditional on VISA I vs. VISA 2.
|
|
; {14} 3/27/90 SS Removed the conditional code to correct for polarity of burn-in
|
|
; jumper on Elsie's VISA1.
|
|
; {13} 3/26/90 SS Made the critical test bit an equate, instead of an ugly
|
|
; hardcoded number. Also, added an instruction to zero out the
|
|
; results register (d6) before calling each non-critical test.
|
|
; Removed the runtime check for the VISA decoder which prevented
|
|
; the non-critical tests from running on an Elsie.
|
|
; {12} 3/23/90 JJ Added conditional to do correct check for Burnin for VISA1.
|
|
; <6> 3/26/90 CV Rolling in changes from mainproj. Original comments below.
|
|
; {11} 3/21/90 SS Moved the Egret initialization code from StartInit.a to here
|
|
; after the RAM tests.
|
|
; {10} 3/19/90 SS Added a vector table for the test manager which is Elsie
|
|
; specific (i.e., it points to things as if ROM started at
|
|
; A00000). Added a runtime check to decide which vector table to
|
|
; use.
|
|
; <5> 3/12/90 CV Rolling in changes from mainproj. Original comments below.
|
|
; {9} 3/9/90 SS Look for RBI PRAM signature in 2 locations (primary and
|
|
; alternate) for power fail recovery operation.
|
|
; <4> 3/2/90 CV Replacing file with file from mainproj.
|
|
; <8> 2/27/90 SS Added support for the critical/non-critical flag in the test
|
|
; table. Also added support for testing for the burnin jumper on
|
|
; systems that have a VISA decoder.
|
|
; <7> 2/16/90 SS Removed dummy entry in the non-critical startup test table.
|
|
; Also added a revision flag to all statements which changed for
|
|
; Ericson.
|
|
; <6> 2/13/90 MA Removed PramTest from the non-critical power-on test table.
|
|
; <5> 2/12/90 MA NCTest table has crit/noncrit bit in ErrCode. Added macros to
|
|
; build NCTestTable. Added check in NCTest loop to see how to
|
|
; handle error (crit or non crit). NC Tests skipped for Elsie for
|
|
; now. Preserve A1 between calls to RDXByte. NonCrit test loop
|
|
; now saves A1.
|
|
; <3> 1/3/90 SES Made changes for Mark ApplemanAdded FMCCacheTest to the
|
|
; NCTestTable. Removed the OSSCntrTest (the OSS sys. counter has
|
|
; gone away).
|
|
; <2> 12/26/89 GMR Added call to non-critical RPU test.
|
|
; <3.2> 12/8/89 GMR Use RPUReset, now defined in HardwareEqu.a, for the write offset
|
|
; to the RPU chip.
|
|
; <3.1> 12/7/89 GMR NEEDED FOR ZONE5: Updated Level7 int handler for Zone-5 parity
|
|
; interrupts.
|
|
; <3.0> 11/21/89 MSH Power on command had too many things going on.
|
|
; <2.9> 11/15/89 KON corrected bad (dog) conditional - ENDIF was being used as a
|
|
; label
|
|
; <2.8> 11/15/89 GMR NEEDED FOR ZONE5. Modified checkForParity to enable parity if
|
|
; the RPU chip is present.
|
|
; <2.7> 11/13/89 SES Added diagnostics for FMC shift register, OSS registers, counter
|
|
; and interrupt.
|
|
; <2.6> 11/11/89 rle needed for ZoneV: fixed bugs inadvertantly introduced when
|
|
; rewriting STStartUp: updated board burnin algorithm for ZoneV,
|
|
; altered warmstart algorithm to support board burnin
|
|
; <2.5> 11/3/89 JJJ Changed conditional to allow warmstart in non-RBV, non-Universal
|
|
; builds.
|
|
; <2.4> 10/7/89 GMR NEEDED FOR ZONE5: Changed SetSCCIopBypass to no longer returns
|
|
; error in d6, since it's used by the serial test manager. Now
|
|
; just sets Z flag if good exit.
|
|
; <2.3> 8/22/89 GMR Added call to power manager to turn on everything except modem.
|
|
; <2.2> 7/25/89 CCH Changed to adjust exception vectors to new ROM image location if
|
|
; forRomulator flag is set. Also sets warmstart flag in case
|
|
; Romulator is running on an old ROM.
|
|
; <2.1> 7/15/89 GMR Exported SetVectorTable for use by USTTestMgr. Made
|
|
; jGetHardwareInfo turn off interrupts before calling
|
|
; GetHardwareInfo.
|
|
; <2.0> 6/28/89 GMR Moved call to BootBeep after RomChecksum, to delay for refresh
|
|
; before SizeMem. Made checkForParity more robust (check both
|
|
; states of parity bit). Setup RAM vector table before calling
|
|
; non-critical tests, so they don't need to.
|
|
; <1.9> 6/26/89 GMR Changed to use (sp) instead of sp when referencing memory chunk
|
|
; table, to work with new size memory output. Exits with a6
|
|
; pointing to chunk table, and stack pointer initialized to 32K
|
|
; above base of 1st bank.
|
|
; <1.8> 6/17/89 GMR Allocated a real stack at 32K above base of RAM for non-critical
|
|
; tests, so they won't blow away bootGlobs when using stack. Fixed
|
|
; register bug in checkForParity.
|
|
; <1.7> 6/13/89 GMR Added calls to Gary D's fast Mod3Test.
|
|
; <1.6> 6/13/89 GGD Modified to work with latest version of Beep.a, leave cache on,
|
|
; pass VIA1 base to Beep calls in A5.
|
|
; <1.5> 6/12/89 GMR Optimized parity scan using movem of 4 longs at a time.
|
|
; <1.4> 6/12/89 GMR Added scan through memory on parity machines on warmstart, and
|
|
; execute ram tests if scan generates parity error.
|
|
; <1.3> 6/11/89 GGD Fixed wrong register bug in UStarttest1, and typo in SetupUSP.
|
|
; <1.2> 6/11/89 GMR Fixed Int level 6 to make universal, and some assembly bugs.
|
|
; <1.1> 6/11/89 GMR Removed INCLUDES, now in header file which includes all others.
|
|
; <1.0> 6/11/89 GMR Added new universal StartTest files for first time to EASE.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
INCLUDE 'UniversalEqu.a' ;
|
|
|
|
StartTest PROC
|
|
|
|
eXPoRT testchk ; •••••••••••••••••••••••• Ack ••••••••••••••••
|
|
|
|
EXPORT StartTest1
|
|
EXPORT JGetHardwareInfo
|
|
EXPORT JGetExtHardwareInfo
|
|
EXPORT USTPMGRSendByte ; <13> ag
|
|
EXPORT USTPMGRRecvByte ; <H3>
|
|
EXPORT ReadPramSig
|
|
EXPORT USTPMGRSendCommand
|
|
EXPORT USTPmgrTurnOn ;export it for the test manager
|
|
EXPORT USTInit
|
|
EXPORT SizeV8VRAM ; <32>
|
|
EXPORT TMVectors
|
|
EXPORT ElsieTMVectors ; <19>
|
|
IMPORT SetVectorTable ;
|
|
IMPORT SetupForExecuteDTM ; Needed to use CTE v2.1 from Startup. HAL
|
|
IMPORT GetHardwareInfo
|
|
IMPORT GetExtHardwareInfo
|
|
IMPORT SetupBases
|
|
IMPORT BaseOfROM
|
|
IMPORT StartInit1
|
|
IMPORT BootBeep6
|
|
IMPORT SizeMemory
|
|
IMPORT StartUpROMTest
|
|
IMPORT Mod3Test
|
|
IMPORT dynamic_bussize_test
|
|
IMPORT Error1Handler
|
|
IMPORT NCErrorHandler
|
|
IMPORT GoTM
|
|
IMPORT SetSCCIopBypass
|
|
IMPORT EgretInit ; <GAA><16><11>
|
|
IMPORT SendEgretCmd ;<22>
|
|
IMPORT RBIMgr
|
|
IMPORT RdXByte
|
|
IMPORT WrXByte
|
|
IMPORT ClkWpOff
|
|
IMPORT diagROMentry ;<31>
|
|
IMPORT SendCudaCmd ; <SM3> rb
|
|
IMPORT CudaInit ; <SM3> rb
|
|
IMPORT USTGetSubTest ; <SM3> rb
|
|
IMPORT PDMBeep
|
|
IMPORT TNTBootBeep
|
|
IMPORT GetCPUIDReg
|
|
|
|
;---------------------------------------------------------------------------
|
|
;
|
|
; This exception table is used by the Ikki Test Manager and the power up
|
|
; test code. The 68020 Vector base register is pointed at this table.
|
|
;
|
|
; Aladdin code has these vectors also, however they are not accessible in
|
|
; the 68000 environment. They are copied to RAM after completion of the first
|
|
; set of power up tests.
|
|
;
|
|
;---------------------------------------------------------------------------
|
|
|
|
WITH DecoderKinds,DecoderInfo
|
|
|
|
;
|
|
; The folling vector table is for use by Elsie only. It is needed because the base of
|
|
; Elsie's ROM is different than for other Mac32 machines.
|
|
;
|
|
|
|
ElsieROMBase EQU $40A00000 ;Elsie's base of ROM <10><SM14> rb
|
|
|
|
ElsieTMVectors ; <10>
|
|
dc.l $00002000 ;$00 space for initial SP <10>
|
|
dc.l StartTest1 -BaseOfROM + ElsieROMBase ;$04 space for initial PC <10>
|
|
dc.l BusError -BaseOfROM + ElsieROMBase ;$08 Bus Error vector <10>
|
|
dc.l AdrError -BaseOfROM + ElsieROMBase ;$0C Address error vector <10>
|
|
dc.l illError -BaseOfROM + ElsieROMBase ;$10 illegal inst error vector <10>
|
|
dc.l ZerError -BaseOfROM + ElsieROMBase ;$14 zero divide <10>
|
|
dc.l ChkError -BaseOfROM + ElsieROMBase ;$18 Chk,Chk2 instructions <10>
|
|
dc.l xTrapx -BaseOfROM + ElsieROMBase ;$1C cpTrapcc,Trapcc,TrapV <10>
|
|
dc.l PrivError -BaseOfROM + ElsieROMBase ;$20 Privilege violation <10>
|
|
dc.l Trace -BaseOfROM + ElsieROMBase ;$24 Trace bit <10>
|
|
dc.l LineA -BaseOfROM + ElsieROMBase ;$28 line A trap <10>
|
|
dc.l LineF -BaseOfROM + ElsieROMBase ;$2C line F trap <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$30 not assigned <10>
|
|
dc.l cpProtocol -BaseOfROM + ElsieROMBase ;$34 cp protocol violation <10>
|
|
dc.l FormatX -BaseOfROM + ElsieROMBase ;$38 format error <10>
|
|
dc.l SpurInterrupt -BaseOfROM + ElsieROMBase ;$3C unitialized interrupt <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$40 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$44 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$48 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$4C not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$50 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$54 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$58 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$5C not assigned <10>
|
|
dc.l SpurInterrupt -BaseOfROM + ElsieROMBase ;$60 spurious interrupt <10>
|
|
dc.l IntLevel1 -BaseOfROM + ElsieROMBase ;$64 Level 1 interrupt <10>
|
|
dc.l IntLevel2 -BaseOfROM + ElsieROMBase ;$68 Level 2 interrupt <10>
|
|
dc.l IntLevel3 -BaseOfROM + ElsieROMBase ;$6C Level 3 interrupt <10>
|
|
dc.l IntLevel4 -BaseOfROM + ElsieROMBase ;$70 Level 4 interrupt <10>
|
|
dc.l IntLevel5 -BaseOfROM + ElsieROMBase ;$74 Level 5 interrupt <10>
|
|
dc.l IntLevel6 -BaseOfROM + ElsieROMBase ;$78 Level 6 interrupt <10>
|
|
dc.l IntLevel7 -BaseOfROM + ElsieROMBase ;$7C Level 7 interrupt NMI) <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$80 Trap #0 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$84 Trap #1 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$88 Trap #2 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$8C Trap #3 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$90 Trap #4 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$94 Trap #5 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$98 Trap #6 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$9C Trap #7 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$A0 Trap #8 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$A4 Trap #9 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$A8 Trap #10 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$AC Trap #11 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$B0 Trap #12 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$B4 Trap #13 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$B8 Trap #14 <10>
|
|
dc.l Trap#N -BaseOfROM + ElsieROMBase ;$BC Trap #15 <10>
|
|
dc.l FPCP#1 -BaseOfROM + ElsieROMBase ;$C0 FPCP bra or set on unordered cond<10>
|
|
dc.l FPCP#2 -BaseOfROM + ElsieROMBase ;$C4 FPCP inexact result <10>
|
|
dc.l FPCP#3 -BaseOfROM + ElsieROMBase ;$C8 FPCP divide by zero <10>
|
|
dc.l FPCP#4 -BaseOfROM + ElsieROMBase ;$CC FPCP underflow <10>
|
|
dc.l FPCP#5 -BaseOfROM + ElsieROMBase ;$D0 FPCP operand error <10>
|
|
dc.l FPCP#6 -BaseOfROM + ElsieROMBase ;$D4 FPCP overflow <10>
|
|
dc.l FPCP#7 -BaseOfROM + ElsieROMBase ;$D8 FPCP signaling NAN <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$DC not assigned <10>
|
|
dc.l PMMUConfig -BaseOfROM + ElsieROMBase ;$E0 PMMU configuration <10>
|
|
dc.l PMMUillegal -BaseOfROM + ElsieROMBase ;$E4 PMMU illegal operation <10>
|
|
dc.l PMMUAccess -BaseOfROM + ElsieROMBase ;$E8 PMMU access level violation<10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$EC not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$F0 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$F4 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$F8 not assigned <10>
|
|
dc.l NotAss -BaseOfROM + ElsieROMBase ;$FC not assigned <10>
|
|
|
|
;
|
|
; The following vector table is for use with all Mac32 machines except Elsie.
|
|
;
|
|
|
|
TMVectors
|
|
dc.l $00002000 ;$00 space for initial SP
|
|
dc.l StartTest1 -BaseOfROM + RomStart ;$04 space for initial PC
|
|
dc.l BusError -BaseOfROM + RomStart ;$08 Bus Error vector
|
|
dc.l AdrError -BaseOfROM + RomStart ;$0C Address error vector
|
|
dc.l illError -BaseOfROM + RomStart ;$10 illegal inst error vector
|
|
dc.l ZerError -BaseOfROM + RomStart ;$14 zero divide
|
|
dc.l ChkError -BaseOfROM + RomStart ;$18 Chk,Chk2 instructions
|
|
dc.l xTrapx -BaseOfROM + RomStart ;$1C cpTrapcc,Trapcc,TrapV
|
|
dc.l PrivError -BaseOfROM + RomStart ;$20 Privilege violation
|
|
dc.l Trace -BaseOfROM + RomStart ;$24 Trace bit
|
|
dc.l LineA -BaseOfROM + RomStart ;$28 line A trap
|
|
dc.l LineF -BaseOfROM + RomStart ;$2C line F trap
|
|
dc.l NotAss -BaseOfROM + RomStart ;$30 not assigned
|
|
dc.l cpProtocol -BaseOfROM + RomStart ;$34 cp protocol violation
|
|
dc.l FormatX -BaseOfROM + RomStart ;$38 format error
|
|
dc.l SpurInterrupt -BaseOfROM + RomStart ;$3C unitialized interrupt
|
|
dc.l NotAss -BaseOfROM + RomStart ;$40 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$44 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$48 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$4C not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$50 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$54 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$58 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$5C not assigned
|
|
dc.l SpurInterrupt -BaseOfROM + RomStart ;$60 spurious interrupt
|
|
dc.l IntLevel1 -BaseOfROM + RomStart ;$64 Level 1 interrupt
|
|
dc.l IntLevel2 -BaseOfROM + RomStart ;$68 Level 2 interrupt
|
|
dc.l IntLevel3 -BaseOfROM + RomStart ;$6C Level 3 interrupt
|
|
dc.l IntLevel4 -BaseOfROM + RomStart ;$70 Level 4 interrupt
|
|
dc.l IntLevel5 -BaseOfROM + RomStart ;$74 Level 5 interrupt
|
|
dc.l IntLevel6 -BaseOfROM + RomStart ;$78 Level 6 interrupt
|
|
dc.l IntLevel7 -BaseOfROM + RomStart ;$7C Level 7 interrupt NMI)
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$80 Trap #0
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$84 Trap #1
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$88 Trap #2
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$8C Trap #3
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$90 Trap #4
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$94 Trap #5
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$98 Trap #6
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$9C Trap #7
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$A0 Trap #8
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$A4 Trap #9
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$A8 Trap #10
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$AC Trap #11
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$B0 Trap #12
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$B4 Trap #13
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$B8 Trap #14
|
|
dc.l Trap#N -BaseOfROM + RomStart ;$BC Trap #15
|
|
dc.l FPCP#1 -BaseOfROM + RomStart ;$C0 FPCP bra or set on unordered cond
|
|
dc.l FPCP#2 -BaseOfROM + RomStart ;$C4 FPCP inexact result
|
|
dc.l FPCP#3 -BaseOfROM + RomStart ;$C8 FPCP divide by zero
|
|
dc.l FPCP#4 -BaseOfROM + RomStart ;$CC FPCP underflow
|
|
dc.l FPCP#5 -BaseOfROM + RomStart ;$D0 FPCP operand error
|
|
dc.l FPCP#6 -BaseOfROM + RomStart ;$D4 FPCP overflow
|
|
dc.l FPCP#7 -BaseOfROM + RomStart ;$D8 FPCP signaling NAN
|
|
dc.l NotAss -BaseOfROM + RomStart ;$DC not assigned
|
|
dc.l PMMUConfig -BaseOfROM + RomStart ;$E0 PMMU configuration
|
|
dc.l PMMUillegal -BaseOfROM + RomStart ;$E4 PMMU illegal operation
|
|
dc.l PMMUAccess -BaseOfROM + RomStart ;$E8 PMMU access level violation
|
|
dc.l NotAss -BaseOfROM + RomStart ;$EC not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$F0 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$F4 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$F8 not assigned
|
|
dc.l NotAss -BaseOfROM + RomStart ;$FC not assigned
|
|
|
|
|
|
BusError
|
|
btst #beok,d7 ;are we expecting this BusError?
|
|
beq.s @10 ;no, must be a baddie
|
|
move.l a5,a7 ;yes, restore sp to caller's original
|
|
RTS6 ;then exit to caller's return point
|
|
@10
|
|
or.w #BECode,d7 ;BusError exception code
|
|
bra.s JmpHandler
|
|
AdrError
|
|
or.w #ADCode,d7 ;Address Error exception code
|
|
bra.s JmpHandler
|
|
illError
|
|
or.w #ILCode,d7 ;illegal Error exception code
|
|
bra.s JmpHandler
|
|
ZerError
|
|
or.w #ZDCode,d7 ;Zero divide Error exception code
|
|
bra.s JmpHandler
|
|
ChkError
|
|
or.w #CICode,d7 ;Check inst Error exception code
|
|
bra.s JmpHandler
|
|
xTrapx
|
|
or.w #TPCode,d7 ;cpTrapcc,Trapcc,TrapV exception code
|
|
bra.s JmpHandler
|
|
PrivError
|
|
or.w #PVCode,d7 ;Privilege violation exception code
|
|
bra.s JmpHandler
|
|
Trace
|
|
or.w #TECode,d7 ;Trace exception code
|
|
bra.s JmpHandler
|
|
LineA
|
|
or.w #ATCode,d7 ;Line A exception code
|
|
bra.s JmpHandler
|
|
LineF
|
|
or.w #FTCode,d7 ;Line F exception code
|
|
bra.s JmpHandler
|
|
NotAss
|
|
or.w #UNCode,d7 ;unassigned exception code
|
|
bra.s JmpHandler
|
|
cpProtocol
|
|
or.w #CPCode,d7 ;CP protocol violation
|
|
bra.s JmpHandler
|
|
FormatX
|
|
or.w #FMCode,d7 ;format exception
|
|
bra.s JmpHandler
|
|
SpurInterrupt
|
|
or.w #SICode,d7 ;spurious interrrupt exception code
|
|
bra.s JmpHandler
|
|
Trap#N
|
|
or.w #TNCode,d7 ;Trap inst exception code
|
|
bra.s JmpHandler
|
|
IntLevel1
|
|
or.w #L1Code,d7 ;Interrupt level 1 code
|
|
bra.s JmpHandler
|
|
IntLevel2
|
|
or.w #L2Code,d7 ;Interrupt level 2 code
|
|
bra.s JmpHandler
|
|
IntLevel3
|
|
or.w #L3Code,d7 ;Interrupt level 3 code
|
|
bra.s JmpHandler
|
|
IntLevel4
|
|
or.w #L4Code,d7 ;Interrupt level 4 code
|
|
bra.s JmpHandler
|
|
|
|
IntLevel5
|
|
or.w #L5Code,d7 ;Interrupt level 5 code
|
|
;
|
|
JmpHandler
|
|
bra ExceptionHandler ;...island to handler...
|
|
|
|
IntLevel6
|
|
or.w #L6Code,d7 ;Interrupt level 6 code, jerk power cord on MacII's
|
|
moveq #0,d2 ;no hint <1.2>
|
|
BSR6 JGetHardwareInfo ;Find base addresses for our machine <1.2>
|
|
move.l VIA2Addr(a0),a0 ;point to VIA 2 base <1.2>
|
|
bset #Poff,VDirB(a0) ;set power off direction bit
|
|
bclr #Poff,VBufB(a0) ;and jerk the power cord
|
|
@die bra.s @die ;and wait fo....cough...choke
|
|
|
|
IntLevel7
|
|
;----------------------------------------------------------------------------
|
|
;
|
|
; This interrupt handler has to deal with potentially intentional parity errors
|
|
; it detects this by looking at a signature in d0 to determine if a parity
|
|
; error is expected.
|
|
;
|
|
;----------------------------------------------------------------------------
|
|
|
|
btst.l #beok,d7 ;are bus errors OK?
|
|
beq.s @notParity ;no, then level 7's aren't allowed either
|
|
|
|
cmp.l #PGCParity,d0 ;is this an expected PGC parity error?
|
|
bne.s @notRBV ;continue if not
|
|
|
|
move.l a5,a7 ;restore sp to caller's orginal <v2.8>
|
|
movea.l DecoderInfo.VIA1Addr(a0),a1 ;Get VIA1 base address
|
|
move.b vBufB(a1),d1 ;read Via register <v2.8>
|
|
bclr.b #vPGCErr,vDirB(a1) ;change direction to input <v2.9>
|
|
beq.s @dataValid ;if already an input, data is already valid <v2.9>
|
|
move.b vBufB(a1),d1 ;read Via register <v2.8>
|
|
bset.b #vPGCErr,vDirB(a1) ;change direction back to output <v2.9>
|
|
|
|
@dataValid ; <v2.9>
|
|
btst #vPGCErr,d1 ;is this a real parity error? <v2.8>
|
|
bne.s @notParity ;no, handle normal NMI <v2.8>
|
|
bset #vPGCEnb,VBufB(a1) ;disable parity checking
|
|
tst.b (a1) ;avoid any race conditions <v3.0>
|
|
bclr #vPGCEnb,VBufB(a1) ;enable PGC parity interrupts
|
|
tst.b (a1) ;avoid any race conditions
|
|
RTS6 ;back to normal processing
|
|
|
|
@notRBV
|
|
|
|
cmp.l #RPUParity,d0 ;is this an expected RPU parity error?
|
|
bne.s @notRPU ;continue if not
|
|
|
|
;else, a0 = decoder info ptr
|
|
move.l a5,a7 ;restore sp to caller's orginal
|
|
movea.l DecoderInfo.OSSAddr(a0),a1 ;get OSS address
|
|
move.w OSSIntStat(a1),d1
|
|
btst #OSSIntRPU,d1 ;did the RPU cause the interrupt?
|
|
beq.s @notParity ;no, handle normal NMI
|
|
|
|
movea.l DecoderInfo.RPUAddr(a0),a1 ;Get RPU base address
|
|
st.b rpuReset(a1) ;reset serial ptr
|
|
move.l (a1),d1
|
|
bset.l #16,d1 ;clear the parity error
|
|
move.l d1,(a1)
|
|
|
|
RTS6 ;return
|
|
|
|
@notRPU
|
|
|
|
@notParity
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #L7Code,d7 ;Interrupt level 7 code
|
|
bset #nmi,d7 ;set NMI received bit
|
|
bra.s ExceptionHandler
|
|
|
|
|
|
FPCP#1
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #F1Code,d7 ;FPCP bra or set on unordered cond
|
|
bra.s ExceptionHandler
|
|
FPCP#2
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #F2Code,d7 ;FPCP inexact result
|
|
bra.s ExceptionHandler
|
|
FPCP#3
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #F3Code,d7 ;FPCP divide by zero
|
|
bra.s ExceptionHandler
|
|
FPCP#4
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #F4Code,d7 ;FPCP underflow
|
|
bra.s ExceptionHandler
|
|
FPCP#5
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #F5Code,d7 ;FPCP operand error
|
|
bra.s ExceptionHandler
|
|
FPCP#6
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #F6Code,d7 ;FPCP overflow
|
|
bra.s ExceptionHandler
|
|
FPCP#7
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #F7Code,d7 ;FPCP signaling NAN
|
|
bra.s ExceptionHandler
|
|
PMMUConfig
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #PCCode,d7 ;PMMU configuration
|
|
bra.s ExceptionHandler
|
|
PMMUillegal
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #PICode,d7 ;PMMU illegal operation
|
|
bra.s ExceptionHandler
|
|
PMMUAccess
|
|
and.w #$FF,d7 ;clear high byte of low word of d7
|
|
or.w #PACode,d7 ;PMMU access level violation
|
|
* bra.s ExceptionHandler ;
|
|
|
|
ExceptionHandler
|
|
bset #excp,d7 ;set exception flag, why not?
|
|
move.l sp,d6 ;save sp in case needed for stack frame post mortum
|
|
move.l #aStack,sp ;yes, init stack pointer
|
|
jmp Error1Handler ;go directly to CritErr, then TM
|
|
|
|
|
|
;=================================================================================================
|
|
; Reno ROM resident start up tests
|
|
;=================================================================================================
|
|
|
|
StartTest1
|
|
move.l #aStack,a7 ;set stack pointer value
|
|
clr.l d7 ;clear flags register
|
|
clr.l d6 ;clear minor error code reg
|
|
|
|
;-------------------------------------------------------------------------------------------------
|
|
; Set up the exception vectors
|
|
;-------------------------------------------------------------------------------------------------
|
|
|
|
IF NOT ROMinRAM THEN ; <SM13> rb
|
|
|
|
IF forRomulator THEN ; <2.2>
|
|
TestInRam A0 ;check if running in RAM <2.2>
|
|
beq.s @noAdj ;if not, don't adjust vectors <2.2>
|
|
BigLea BaseOfRom,a0 ;get base of ROM running in RAM <2.2>
|
|
move.l a0,d1 ;use a data register <2.2>
|
|
subi.l #ROMStart,d1 ;calculate conversion offset <2.2>
|
|
lea TMVectors+4,a0 ;get address of vectors <2.2>
|
|
move.w #VTEntries-2,d0 ;get number of entries to adjust <2.2>
|
|
@adj add.l d1,(a0)+ ;convert a vector <2.2>
|
|
dbra d0,@adj ;do all of them <2.2>
|
|
@noAdj ; <2.2>
|
|
ENDIF ; {forRomulator} <2.2>
|
|
|
|
lea ElsieTMVectors,a1 ;First see if we are on an Elsie <10>
|
|
lea StartTest1,a5 ;Get the address of the start vector <10>
|
|
cmpa.l 4(a1),a5 ;Does this agree with where we are? <10>
|
|
beq.s @cont ;Continue if so <10>
|
|
lea TMVectors,a1 ;Otherwise, load the default TM vectors <10>
|
|
|
|
IF forRomulator THEN ; save certain ReAnimator except. vectors<33>
|
|
TestInRAM A0 ; only do the Vector Shuffle if in RAM <33>
|
|
beq.s @cont ; IF we are in RAM ... <33>
|
|
movec vbr,a0 ;find out where our vector table currently is<33>
|
|
move.l BusErrVct(a0),BusErrVct(a1) ; ... then do that Vector Shuffle Thang <33>
|
|
move.l AddrVector(a0),AddrVector(a1)
|
|
move.l IlglVector(a0),IlglVector(a1)
|
|
move.l ZeroVector(a0),ZeroVector(a1)
|
|
move.l CheckVector(a0),CheckVector(a1)
|
|
move.l TrapVVector(a0),TrapVVector(a1)
|
|
move.l PrivlgVector(a0),PrivlgVector(a1)
|
|
move.l TraceVector(a0),TraceVector(a1)
|
|
move.l DebugVector(a0),DebugVector(a1)
|
|
move.l FmtErrVect(a0),FmtErrVect(a1)
|
|
move.l BadIntVector(a0),BadIntVector(a1)
|
|
move.l BkptVector(a0),BkptVector(a1)
|
|
ENDIF ; {forRomulator} <33>
|
|
|
|
@cont movec a1,VBR ;VBR points to our exception table <10>
|
|
|
|
ENDIF ; <SM13> rb
|
|
|
|
move.l a7,a5 ;copy sp for BusError handler
|
|
|
|
moveq.l #0,d2
|
|
BSR6 JGetHardwareInfo ;get hardware info about this machine
|
|
|
|
;-------------------------------------------------------------------------------------------------
|
|
; Check for diagnostic ROMs, jump to them if found, else return
|
|
;-------------------------------------------------------------------------------------------------
|
|
CheckDiagRoms
|
|
IF forRomulator THEN ; check if we are ReAnimator™ing <33>
|
|
TestInRAM A1 ; are we running in ram? <33>
|
|
bne.s @noDiagRom ; dont check for diagnostic ROMs if running from RAM<33>
|
|
nop ; Why are we even doing TestInRAM?
|
|
ENDIF ; {forRomulator} <33>
|
|
@noDiagRom
|
|
bclr #beok,d7 ;clear the BusError is OK flag
|
|
|
|
|
|
;------------------------------------------------------------------------------------------------- <SM23> begin
|
|
; Check for factory loopback on VIA Sound Volume lines. On Mac,MacPP,NuMac the
|
|
; jumper shorts SV2 to SV1. On newer Macs, the jumper simply grounds
|
|
; the SV1 line (bit 0, VBufA), except on Normandy, where it grounds bit 2, VBufB.
|
|
; The VIA is assumed to be initialized to a normal state. SV1 is changed here to
|
|
; be an input for Mac,MacPP,NuMac. If loopback found, set test bit in d7 flags,
|
|
; run tests, and jump to Test Manager instead of returning to OS start code.
|
|
; For Mac,MacPP we rely on the fact that the VIA inputs read as
|
|
; [ZoneV jumpers the SCC WrReq pin of the OSS instead of the SV1 line on the VIA.] <v2.6>
|
|
;-------------------------------------------------------------------------------------------------
|
|
CheckLoopBack
|
|
moveq.l #0,d2 ;get universal information
|
|
BSR6 JGetHardwareInfo ;
|
|
movea.l VIA1Addr(a0),a2 ;get VIA1 base address
|
|
|
|
cmp.b #NormandyDecoder,d2 ;is this a Normandy decoder?
|
|
bne.s @checkMDUorOSS ;no, check for other types of machines
|
|
|
|
;Normandy decoder: Jumper shows up on bit 2 of VIA1 port B
|
|
btst #2,vBufB(a2) ;is the jumper installed?
|
|
bne @checkROMs ;if not, continue startup as normal
|
|
bra @HasJumper ;else, we're in burnin
|
|
|
|
@checkMDUorOSS
|
|
|
|
cmp.b #OSSFMCDecoder,d2 ;OSS decoder has a jumper grounding SCC WrReq
|
|
bne.s @DefaultJumper ;check the default jumper location if not OSS
|
|
|
|
move.l OSSAddr(a0),a3 ;point to OSS base <v2.6>
|
|
btst #1,OSSInpStat(a3) ;is the jumper installed? <v2.6>
|
|
beq @checkROMs ;go check ROMs if not (bit is inverted by OSS) <v2.6>
|
|
bra @HasJumper ;else, we're in burnin
|
|
|
|
@DefaultJumper ; <17><18>
|
|
;
|
|
; OK - now's where we check the jumper. This test should be done on all machines
|
|
; prior to and including the MacLC. However, for machines after that, we should
|
|
; only perfrom this test if the box flag is contained in a list of post LC machines
|
|
; that have a burnin edge connector.
|
|
;
|
|
|
|
asr.w #8,d2 ;get the box flag into the lsb
|
|
cmp.b #boxMacLC,d2 ;are we an LC or before?
|
|
ble.s @CheckJumper ;go ahead and check the jumper if so
|
|
;
|
|
;else, we should only check the jumper if this machine's box flag is contained in
|
|
;the table of post LC machines that still have a burnin connector
|
|
;
|
|
|
|
lea PostLC_BIJumper_boxes,a3 ;get a pointer to the table
|
|
|
|
@JumperLookup
|
|
move.b (a3)+,d3 ;get the next box flag
|
|
cmp.b #boxUnknown,d3 ;is this the end of the table?
|
|
beq.s @SCSICheck ;do the SCSI check anyway if so
|
|
cmp.b d2,d3 ;else, are we in the table?
|
|
bne.s @JumperLookup ;keep looking if not
|
|
;OK - we're in the table, check for jumper
|
|
|
|
@CheckJumper ;default jumper check: bit 0 of port A of VIA1
|
|
bclr.b #SV1,vDIRA(a2) ;make SV1 an input
|
|
bclr.b #SV2,vBufA(a2) ;set SV2 bit to 0 volts (which will ground SV1 if jumpered)
|
|
|
|
btst #SV1,vBufA(a2) ;is the jumper installed?
|
|
beq @HasJumper ;branch if the jumper is installed
|
|
;else, jumper is not installed: check for SCSI jumper
|
|
@SCSICheck
|
|
move.l #SCSIBILocs,d3 ;get the location of the SCSI burnin bytes
|
|
|
|
@CheckSCSISig
|
|
bsr6 ReadPramSig ;get the signature
|
|
cmp.l #SCSIBIBytes,d4 ;is this our location?
|
|
beq.s @hasSCSISig ;branch if so
|
|
move.w #$0000,d3 ;else, clear out one signature location
|
|
swap d3 ;prepare the other location
|
|
bne.s @CheckSCSISig ;and keep looking if we haven't checked both locs yet
|
|
bra @checkROMs ;if we get here then we don't have any jumper
|
|
|
|
@hasSCSISig ;we want to look for the SCSI jumper now
|
|
moveq.l #0,d2 ;get the universal information again
|
|
bsr6 jGetHardwareInfo ;make the call
|
|
movea.l VIA1Addr(a0),a2 ;prepare for possible PRAM access
|
|
|
|
btst.l #SCSIExists,d0 ;do we have a 53C80?
|
|
beq.s @hasC96 ;branch if not
|
|
|
|
movea.l SCSIAddr(a0),a3 ;get the base address of the 53C80 registers
|
|
move.b sCSR(a3),d3 ;get the current SCSI bus phase
|
|
and.b #(aMSG|aCD|aIO),d3 ;mask out the appropriate bits
|
|
cmp.b #aMSG,d3 ;does our phase match? (MSG asserted, CD and IO not)
|
|
bne.s @ZeroPRAM ;go init PRAM if not
|
|
|
|
bra.s @HasJumper ;SCSI jumper installed
|
|
|
|
@hasC96
|
|
movea.l SCSI96Addr1(a0),a3 ;assume SCSI1 is the external bus
|
|
btst.l #SCSI96_2Exists,d0 ;do we have a SCSI2 bus?
|
|
beq.s @SCSI1Only ;branch if so (means SCSI1 is only bus
|
|
movea.l SCSI96Addr2(a0),a3 ;else, SCSI bus 2 is the external bus
|
|
@SCSI1Only
|
|
move.b rSTA(a3),d3 ;get the bus control signals
|
|
and.b #iPhaseMsk,d3 ;mask out the bus phase information
|
|
cmp.b #%100,d3 ;look for our phase
|
|
beq.s @HasJumper ;we have the jumper if this is a match
|
|
|
|
@ZeroPRAM
|
|
;
|
|
;Factory escape! The SCSI signature was in PRAM, but there is no SCSI jumper!
|
|
;Zero PRAM to remove any leftover RBI stuff and assure that the OS initializes it
|
|
;from scratch.
|
|
;
|
|
bsr6 ClkWpOff ;un-write protect the PRAM first
|
|
move.w #$FF,d3 ;start at the end of PRAM
|
|
@ZeroPRAMLoop
|
|
moveq.l #0,d2 ;write zero to next location
|
|
move.w d3,d1 ;get the next address to write to
|
|
bsr6 WrXByte ;go zero out this byte
|
|
dbra.w d3,@ZeroPRAMLoop ;keep going until it's all gone
|
|
bra.s @CheckROMs ;and continue with normal bootup operation
|
|
|
|
@HasJumper
|
|
bset #test,d7 ;jumper found, set flag bit for later
|
|
|
|
;-------------------------------------------------------------------------------------------------
|
|
; if here, then we are in board burn-in. <v1.1><9>
|
|
; See if the RBI signature bytes are valid. <9>
|
|
; There are 2 possible locations for these bytes. The PRAM addresses of these 2 locations <9>
|
|
; are contained in the 2 halves of a long word. Get this long word and look in both possible <9>
|
|
; locations. If either location contains a valid signature, go to the RBI manager. <9>
|
|
;-------------------------------------------------------------------------------------------------
|
|
|
|
move.l #SigLocs,d3 ;Locations of signature bytes <v1.1><7><9>
|
|
|
|
@CheckRBISig
|
|
bsr6 ReadPramSig ;read the RBI signature from PRAM
|
|
|
|
cmp.l #SigBytes,d4 ;Compare result with the signature <7><9>
|
|
beq RBIMgr ;go to RBIMgr if all bytes correct <v1.1><7><9>
|
|
|
|
move.w #$0000,d3 ;No match here <9>
|
|
swap d3 ;Have we tried both signature locations? <9>
|
|
bne.s @CheckRBISig ;Continue if not <9> <SM23> end
|
|
|
|
@checkROMs
|
|
; ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
|
|
|
|
IF NOT ROMinRAM THEN ; <SM13> rb
|
|
|
|
movec CACR,d0 ; retrieve current CACR <T2>
|
|
bset #CACR_IE_040,d0 ; set 040 "enable I-Cache" bit to see if we're on an 040 <T7>
|
|
movec d0,CACR ; set the bit to see if it sticks
|
|
movec CACR,d0 ; get the value back
|
|
if forRomulator THEN
|
|
bclr #CACR_IE_040,d0 ; leave inst. cache off for now <T7>
|
|
movec d0,cacr ; put it back in cache reg
|
|
else
|
|
btst #CACR_IE_040,d0 ; are we on an 040? <T7>
|
|
endif
|
|
beq.s @notAn040 ; IF we're on an 040 THEN
|
|
MACHINE MC68040 ; switch to 68040 instruction set
|
|
cinva ic ; invalidate the I-cache, leaving it enabled
|
|
bra.s @go ; continue
|
|
MACHINE MC68030 ; switch back to 68030 instructions
|
|
@notAn040 ; ELSE
|
|
movec CACR,d0 ; examine cache control register
|
|
ori.b #((1<<CACR_EI_020_030)|\ ; enable ... <T7>
|
|
(1<<CACR_CI_020_030)),d0 ; ... and flush I-Cache <T7>
|
|
bclr.l #CACR_ED_030,d0 ; disable data cache <T7>
|
|
movec d0,CACR ; do it
|
|
@go ; ENDIF <T2>
|
|
ENDIF ; <SM13> rb
|
|
|
|
;
|
|
; Next, initialize the DFAC (if present) by calling the machine dependant init routine.
|
|
;
|
|
moveq.l #0,d2
|
|
BSR6 JGetHardwareInfo ;first, recreate the universal information
|
|
|
|
; Potential chk needed here to determine if the DFAC HW needs to be initialized...
|
|
; Chk Hardware Type to see if DFAC INIT is required...
|
|
; 1/31/92 gjs <P5>
|
|
|
|
WITH ProductInfo
|
|
move.l SndControlPtr(a1),d3 ; get a pointer to the sound dispatch table
|
|
beq.s @noDFAC ; we're done if there is none
|
|
lea (a1,d3.l),a2 ; dereference the pointer
|
|
move.l (sndDFACInit<<2)(a2),d3 ; and check for a DFAC init routine
|
|
beq.s @noDFAC ; we're done if there is none
|
|
lea @1,a6 ; set the return address <SM13> rb
|
|
jmp (a2,d3.l) ; else, init the DFAC <SM13> rb
|
|
@1 ; <SM13> rb
|
|
ENDWITH
|
|
@noDFAC ;DFAC initialization is done
|
|
|
|
;-------------------------------------------------------------------------------------------------
|
|
; First get the ROMs checksummed to gain confidence in ourselves
|
|
;-------------------------------------------------------------------------------------------------
|
|
|
|
; If the machine has been started up by a 68k emulator, then the Native boot code has
|
|
; already checksumed the ROM (including the additional ROM space used by the emulator)
|
|
|
|
IF NOT ROMinRAM THEN ; skip ROM checksum code for RAM <SM13> rb
|
|
|
|
btst #ProductInfo.has68kEmulator//8,ProductInfo.ExtValid1+3(A1)
|
|
bne.s @NoROMTest ; -> An emulator is responsible for starting up this machine.
|
|
|
|
move.w #ErrROM,d7 ; init major error code
|
|
BSR6 StartUpROMTest ;
|
|
tst.l d6 ; any error?
|
|
bne Error1Handler ; yes, go handle fatal error
|
|
|
|
@NoROMTest
|
|
ENDIF ; <SM13> rb
|
|
clr.w d7 ; clear any residue error code
|
|
|
|
;-------------------------------------------------------------------------------------------------
|
|
; go ahead and make the call to bootbeep to inform the user that we're alive
|
|
;-------------------------------------------------------------------------------------------------
|
|
@Beep moveq.l #0,d2
|
|
BSR6 JGetHardwareInfo
|
|
BSR6 JGetExtHardwareInfo ;
|
|
|
|
IF NOT forSTP601 THEN ; <SM38>
|
|
BSR5 NuBusReset ; Send a Reset to BART (if we have one)
|
|
BSR5 PDS_Reset ; Reset the PDS video cards (if present) for PowerPc machines <MC6>
|
|
BSR6 JGetHardwareInfo
|
|
ENDIF ; <SM38>
|
|
|
|
btst.l #(hwCbPwrMgr+16),d2 ; do we have a pmgr?
|
|
beq.s @noPmgr ; branch if not
|
|
|
|
BSR6 USTPmgrTurnOn ; turn on a bunch of things
|
|
@noPmgr
|
|
|
|
IF forSTP601 THEN ; <SM38>
|
|
moveq.l #0,d2 ;get universal information
|
|
BSR6 JGetHardwareInfo ;
|
|
movea.l DecoderInfo.VIA1Addr(a0),a2 ;get VIA1 base address
|
|
|
|
move.w #$B0,d1
|
|
BSR6 RdXByte
|
|
andi.b #$01,d1
|
|
beq.s @skip_040
|
|
_nkSwitchTo040
|
|
@skip_040
|
|
BSR6 JGetHardwareInfo
|
|
ENDIF ; <SM38>
|
|
|
|
IF NOT forTNTDebug THEN
|
|
BigBSR6 BootBeep6,a0 ; call boot beep subroutine
|
|
ENDIF
|
|
|
|
moveq.l #0,d2 ; <30>
|
|
BSR6 JGetHardwareInfo ; <30>
|
|
Btst.l #ASCExists,D0 ; Do we have an ASC <LW2>
|
|
Beq.s @NoASC ; if not, don't need to <LW2>
|
|
|
|
BigLEA BaseOfROM,A3 ; Get ROMBase <SM31> SAM
|
|
CMP.L ASCAddr(A0),A3 ; Is ASCAddr pointing into the ROM?
|
|
BEQ.S @NoASC ; -> Yes, we don't really have an ASC. Dont whack <SM31>
|
|
|
|
movea.l ASCAddr(a0),a3 ; setup ASC address for BootBeep6 <SM25>
|
|
clr.b $804(a3) ; clear pending interrupt from ASC
|
|
@NoASC ; <LW2>
|
|
BSR6 SizeV8VRAM ; and size video ram (changes memory decodeing) <30>
|
|
|
|
;-------------------------------------------------------------------------------------------------
|
|
; Need to size memory now
|
|
; On exit from SizeMemory,
|
|
; d6 = 0 if sized ok and banks look good, otherwise, FF's in bad byte lanes
|
|
; (sp) = pointer to a memory chunk table with the following format:
|
|
; Start.L, Length.L, ..., $FFFFFFFF
|
|
;-------------------------------------------------------------------------------------------------
|
|
@SizeMem
|
|
move.w #ErrSizeMem,d7 ;just so we will know where we're at if fail
|
|
BSR6 SizeMemory ;(sp) points to memory table
|
|
bne Error1Handler ;error, exit to test manager
|
|
|
|
IF forRomulator THEN ; <2.2>
|
|
TestInRam A1 ;check to see if we're running in RAM <2.2>
|
|
beq.s @inROM ;if not, skip this <2.2>
|
|
movea.l (sp),a0 ;else, get pointer to bootglobs <1.9>
|
|
move.l #WmStConst,StartGlobals.sgWarmStart(a0) ; if in RAM, we want a warmstart <SM11> CSS
|
|
@inROM
|
|
ENDIF ; <2.2>
|
|
|
|
|
|
IF 0 THEN
|
|
;-------------------------------------------------------------------------------------------------
|
|
; Before testing RAM, determine if we have parity, by testing the first long word of ram in
|
|
; all banks, and setting parity flag in d7 to reflect this. Parity is enabled/disabled here.
|
|
;-------------------------------------------------------------------------------------------------
|
|
BSR6 checkForParity
|
|
tst.l d6 ;parity good (or no parity)?
|
|
bne.s @checkRamDisk ;no, test memory like cold start <v2.6>
|
|
ENDIF
|
|
|
|
|
|
; On machine who's start up process is being emulated by a "V0" style emulator/nanokernel, the native <SM31>
|
|
; startup code is responsible for doing the RAM test and boot beep on a cold start. On a warm start
|
|
; the native code is not run; we therefore need to determine if the native code has just run, and if
|
|
; so, play the boot beep.
|
|
|
|
moveq #0,D2
|
|
bsr6 JGetHardwareInfo ; Get the universal info for the 99e99'th time this boot...
|
|
|
|
move.l (SP),A6 ; Put the chunk table pointer into A6 for later
|
|
|
|
; Does the universal info say we're running with an emulator?
|
|
|
|
btst #ProductInfo.has68kEmulator//8,ProductInfo.ExtValid1+3(A1)
|
|
beq @NonEmulatedMachine ; -> An emulator is *not* responsible for starting up this machine.
|
|
|
|
; Check the "has the native cold-start code just run?" flags
|
|
|
|
WITH nkDiagInfo
|
|
move.l (nkDiagInfoPtr),A0 ; Get the address of the nanokernal diag page
|
|
cmpi.l #emuWarmStartConst,DiagWarmStartLow(A0) ; Does the upper long match?
|
|
bne.s @EmuColdStart ; -> Nope, this is a cold start
|
|
cmpi.l #WmStConst,DiagWarmStartHigh(A0) ; Lower long?
|
|
bne.s @EmuColdStart ; -> Cold start
|
|
|
|
; We are doing a WarmStart. We need to run the emulated boot beep code & return to StartInit
|
|
|
|
@EmuWarmStart
|
|
|
|
|
|
cmp.b #HMCDecoder,ProductInfo.DecoderKind(a1) ; are we a PDM?
|
|
bne.l @NotPDM ; no, try tnt
|
|
|
|
bsr.l PDMBeep
|
|
|
|
@NotPDM
|
|
cmp.b #HHeadDecoder,ProductInfo.DecoderKind(a1); are we a TNT?
|
|
bne.l @NotTNT ; no, must be stp
|
|
|
|
bsr6 TNTBootBeep ; <SM41>
|
|
|
|
@NotTNT
|
|
move.l (SP),A6 ; Put the chunk table pointer into A6 for later
|
|
|
|
bra ReturnToStartInit ; -> Emu machines are done
|
|
|
|
; We have just come from the Native Hard/Cold Reset code. It has already played the boot beep so
|
|
; we don't have to. Now comes the fun part. We need to set the "emu" warmstart flag (the only
|
|
; thing that we check to determine if the current boot is cold or warm). This flag lives in the
|
|
; writeprotected diagnostic info block in the Nanokernel's data page. We need to "map" the diag
|
|
; page to a normally mapped page of RAM, write the warmstart constant, and remap the memory back
|
|
; the way it was. Oh, I'm using logical page number 1 (i.e. $1000 - 4k pages). Oh, yeah, the RAM
|
|
; at $1000 never actually gets modified... <SAM>
|
|
|
|
@EmuColdStart
|
|
|
|
move.w #12,D2 ; Shift Count (12 bits in 4k)
|
|
|
|
lea 1,A0 ; Logical page #1 ($1000)
|
|
_nkGetPTEntryGivenPage ; Get its Pte
|
|
move.l D0,D3 ; Save the Pte in D3
|
|
|
|
move.l (nkDiagInfoPtr),D0 ; Get the DiagPage Logical Address
|
|
move.l D0,D5 ; Make a copy
|
|
and.l #4096-1,D5 ; Get the offset into the page
|
|
|
|
lsr.l D2,D0 ; Make it a page number
|
|
|
|
move.l D0,A0 ; Page into A0
|
|
_nkGetPTEntryGivenPage ; Get the Diag Pte
|
|
move.l D0,D4 ; Save it
|
|
|
|
lea 1,A0 ; Get the buffer page number in A0
|
|
lea 1,A1 ; Say page is inited (#1)
|
|
_nkMMUMarkBacking ; Mark this page as outta here
|
|
|
|
lea 1,A0 ; Logical Page number of the buffer
|
|
move.l D4,D0 ; Get the Diag Pte
|
|
lsr.l D2,D0 ; Get its Physical Page number
|
|
move.l D0,A1 ; Set Physical Page
|
|
_nkMMUMarkResidentGlue ; Map the diag's physical address to the buffer's logical addr
|
|
|
|
lea $1000,A0 ; Get our logical starting point
|
|
add.l D5,A0 ; Add in the offset from the start of the diag page
|
|
move.l #'SamB',DiagWarmStartLow(A0) ; Write a great constant to the diag page
|
|
move.l #'WLSC',DiagWarmStartHigh(A0) ; This one too....
|
|
|
|
lea 1,A0 ; Get the lo Page number in A0
|
|
lea 1,A1 ; Say page is inited (#1)
|
|
_nkMMUMarkBacking ; Mark this page as outta here
|
|
|
|
lea 1,A0 ; Get the lo Page number in A0
|
|
move.l D3,D0 ; Get the LoPage's Pte
|
|
lsr.l D2,D0 ; Get its Physical Page number
|
|
move.l D0,A1 ; Set Physical Page
|
|
_nkMMUMarkResidentGlue ; Move the HiPage to the loPage's logical addr
|
|
|
|
ENDWITH
|
|
|
|
|
|
move.l #WmStConst,StartGlobals.sgWarmStart(a6) ; Set the traditional warmstart flag in startglobals
|
|
bra ReturnToStartInit ; Skip all the CTE garbage. Emu machines have native garbage. <SM31>
|
|
|
|
@NonEmulatedMachine
|
|
|
|
cmpi.l #WmStConst,StartGlobals.sgWarmStart(a6) ; Check for warm start <SM11> CSS
|
|
bne.s @checkRamDisk ; -> Cold start. Test RAM (avoiding RAM disk)
|
|
|
|
@NoRAMTest
|
|
clr.w d7 ; Done with warm start testing
|
|
bra.w testchk ; Do warm start
|
|
|
|
@checkRamDisk
|
|
movea.l #-1,a3 ; No RAM disk here
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
; Test ALL banks of RAM now. Keep index into table in a4.
|
|
; Enter with a3=base of RAM disk, if any, else a3=ffffffff
|
|
;-------------------------------------------------------------------------
|
|
@testRam
|
|
IF ROMinRAM | BlackBirdDebug THEN ;••Fix this <SM13> rb
|
|
move.l #WmStConst,StartGlobals.sgWarmStart(a6) ; force warm start <SM13> rb
|
|
ELSE ; <SM13> rb
|
|
move.w #ErrRAMA,d7 ;init error to Bank A error code
|
|
movea.l (sp),a4 ;get ptr to chunk table
|
|
movea.l a4,a5 ;preserve in a5 <1.9>
|
|
@memLoop
|
|
move.l (a4)+,a0 ;get start of bank
|
|
cmpa.l #-1,a0 ;at end of table?
|
|
beq.s @RamPassed ;(-1) means end of table
|
|
move.l (a4)+,d0 ;get length
|
|
move.l a0,a1
|
|
adda.l d0,a1 ;calculate end of bank
|
|
cmpa.l a1,a5 ;above memory chunk table? <1.9>
|
|
bhi.s @atRAMdsk ;no, test complete chunk
|
|
move.l (sp),a1 ;yes, set top to base of chunk table <1.9>
|
|
@atRAMdsk
|
|
cmpa.l a1,a3 ;above RAM disk
|
|
bhi.s @testChunk ;no, test it
|
|
move.l a3,a1 ;yes, set top to base of RAM disk
|
|
@testChunk
|
|
BSR6 Mod3Test ;test this bank <1.7>
|
|
move.l a5,(sp) ;restore pointer in case blown away <1.9>
|
|
tst.l d6
|
|
bne Error1Handler ;failed, go to test manager
|
|
addq.w #1,d7 ;bump to next bank code
|
|
bra.s @memLoop ;passed, test next bank
|
|
ENDIF ; <SM13> rb
|
|
|
|
@RamPassed
|
|
|
|
;-------------------------------------------------------------------------------------------------
|
|
; Finally, test the bus sizing feature of the 020/030
|
|
;-------------------------------------------------------------------------------------------------
|
|
move.w #ErrDynBus,d7 ;preset failed code
|
|
movea.l (sp),a0 ;get ptr to chunk table <1.9>
|
|
movea.l (a0),a0 ;test at base of first bank <1.9>
|
|
bsr6 dynamic_bussize_test ;do this test
|
|
tst.l d6 ;any error here?
|
|
bne Error1Handler ;failed, go to test manager
|
|
|
|
|
|
; From here to the next <HAL> below was changed to support machine dependant test tables
|
|
; and CTE kernel v2.1.
|
|
;/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
;----------------------Non-Critical Diagnostic Tests------------------
|
|
;
|
|
; This section of code executes the RAM based tests. These tests require RAM in
|
|
; order to execute, as apposed to the RAM less tests such as the ROM checksum
|
|
; and the RAM tests above. Because RAM has already been tested before this point,
|
|
; it is assumed that RAM is good enough to rely on.
|
|
;
|
|
;----------------------------------------------------------------------
|
|
testchk
|
|
WITH USTGlobals, RunBits, CPUTestList, USTSubtest
|
|
|
|
moveq #1,D2 ; set the flag telling UST to NOT call SizeMem again! <SM32>
|
|
BSR6 USTInit ; initialize the universal environment
|
|
|
|
IF NOT ROMinRAM THEN ; <SM13> rb
|
|
|
|
move.l PrdctInfPtr(a5),a1 ; set this for NCErrorHandler (trashed by USTInit)
|
|
|
|
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 UST globals pointer
|
|
movea.l CTEGlobals(a5),a0 ; get the CTE globs pointer
|
|
|
|
CASE ON
|
|
GIM_InitInterface (a0),#SIZEOFCTEGLOBALS ;init the CTE interface
|
|
CASE OFF
|
|
|
|
movea.l (sp)+,a5 ; restore the USTGlobals pointer
|
|
moveq.l #Restart,d0 ; init it for restart (at least)
|
|
cmp.l #WmStConst,WarmStartConst(a5) ; is this a warm start?
|
|
beq.s @warmStart ; branch if so
|
|
bset.l #StartupBit,d0 ; else, also set the startup condition <H16>
|
|
|
|
@warmStart
|
|
move.w d0,RunMode(a5) ; store the run mode
|
|
movea.l GlobCPUTestList(a5),a2 ; get the CPU specific test list in a2 <36>
|
|
|
|
movea.l DcdrInfPtr(a5),a0 ; set this for the NCErrorHandler also <H16>
|
|
|
|
@NextTest
|
|
moveq.l #0,d5 ; zero out the test ID register
|
|
move.w TLTest_ID(a2),d5 ; get the next test ID
|
|
cmp.w #-1,d5 ; are we at the end of the table?
|
|
beq.l @done ; all finished with non-critical startups if so
|
|
moveq.l #0,d4 ; zero out the test ID register <H16>
|
|
move.w TLSubTest_ID(a2),d4 ; get the subtest ID (word) <H16>
|
|
movem.l a0-a3/a5,-(sp) ; save some registers
|
|
BigBSR6 SetupForExecuteDTM,a0 ; set up the GI_ExecuteDTM parameters
|
|
|
|
; Check for errors in setting up for the ExecuteDTM and don't try to execute the DTM
|
|
; if any were found (just skip it and move to the next one). At this stage, the only
|
|
; possible error would be if the requested DTM does not apply to a warmstart condition.
|
|
; At this time, the only test I can think of that does apply is the VRAM test:
|
|
|
|
move.l tInfoFunctionEntry(a5),d6
|
|
cmp.l #-1,d6 ; -1 means test not found or does not apply
|
|
beq.s @TestFailure
|
|
move.l sInfoFunctionEntry(a5),d6
|
|
cmp.l #-1,d6 ; -1 means subtest not found or does not apply
|
|
beq.s @TestFailure
|
|
|
|
; No errors setting up for the test, so do it:
|
|
|
|
movea.l CTEGlobals(a5),a0 ; get the globs pointer again - a0 was trashed
|
|
; by SetupForExecuteDTM
|
|
moveq.l #0,d6 ; Zero out the DTM result register. The ROM-based
|
|
; test routines traditionally use d6 as the result
|
|
; register, but the ROM-based test used with CTE
|
|
; will transfer d6 to d0 before returning to the
|
|
; ExecuteDTM routine - from there it's all C code
|
|
; back to here after GIM_ExecuteDTM. So, the rule
|
|
; of thumb here is: clear d6 going in, check
|
|
; d0 coming out.
|
|
|
|
CASE ON
|
|
GIM_ExecuteDTM (a0), EXOPUSERINFO(a5), TINFOUSERINFO(a5), SINFOUSERINFO(a5), EXRESERR(a5)
|
|
CASE OFF
|
|
|
|
tst.l d0 ; any errors? (C functions return result in D0)
|
|
beq.s @testPassed ; continue if not
|
|
move.l d0,d6 ; store the error from the C function where the NCErrorHandler
|
|
; routine expects it to be
|
|
@TestFailure
|
|
movem.l (sp),a0-a3/a5 ; restore them registers (leave stack where it is)
|
|
move.w RunMode(a5),d0 ; get the run mode
|
|
btst.l #StartupBit,d0 ; is this a startup (cold start) condition? <H16>
|
|
beq.s @testPassed ; no, so skip logging results (only store results on cold start) <H16>
|
|
bsr NCErrorHandler ; else, execute the error handler <37>
|
|
btst.l #test,d7 ; are we in test mode?
|
|
bne goTM ; go to test manager if so
|
|
|
|
@testPassed
|
|
movem.l (sp)+,a0-a3/a5 ; restore registers (and adjust the stack appropriately)
|
|
adda.l #sizeofCPUTestList,a2 ; index to next DTM <H16>
|
|
bra.s @NextTest ; go on to next DTM in the list
|
|
|
|
@done ; finished with tests - continue with bootup
|
|
adda.l #SizeOfCTEGlobals,sp ; clean up the stack - remove all traces of CTE, but leave the
|
|
; USTGlobals in place because we have to set a6 to point to the
|
|
; memory chunk table before handing things over to the OS guys
|
|
|
|
ENDWITH
|
|
|
|
;From here to the next <HAL> above was changed to support CTE v2.1. <SM19>end
|
|
|
|
;-------------------------------------------------------------------------
|
|
; Now check the flag bit that might send us to the Test Manager instead
|
|
; of returning to OS start code. This would be that we found a VIA
|
|
; loopback on the SV1 and SV2 lines.
|
|
;-------------------------------------------------------------------------
|
|
|
|
clr.w d7 ;clear out any error code <34>
|
|
btst.l #test,d7 ;any loopback?
|
|
bne goTM ;yes, go directly to Test Manager
|
|
|
|
;
|
|
; Any test failure will have already been logged previously when the test <29>
|
|
; was run at power on.
|
|
;
|
|
ENDIF ; <SM13> rb
|
|
|
|
movea.l USTGlobals.ChunkTable(a5),a6 ;and return with a6 pointing to RAM table<34>
|
|
ReturnToStartInit
|
|
bra.l StartInit1 ; <SM13> rb
|
|
|
|
|
|
;===============================================================================
|
|
; Misc subroutines...
|
|
;===============================================================================
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; Routine: checkForParity
|
|
;
|
|
; Inputs: a6 - return address
|
|
; (sp) - memory chunk table pointer
|
|
;
|
|
; Outputs: d7 - parity bit set on parity
|
|
;
|
|
; Destroys: d0-d2,d4,a0-a5
|
|
;
|
|
; RBV Type Parity: This routine checks each bank for parity RAM, and sets the parity
|
|
; bit in d7 if all banks seem to have parity. If any bank does not have parity, it
|
|
; clears the parity bit. It checks for parity by writing a single 1 to every SIMM, then
|
|
; reading. If no parity chip exists, the parity bit will = 1 (floats) and cause
|
|
; a parity NMI. Parity is enabled/disabled on exit from this routine, if parity
|
|
; was detected/not detected.
|
|
;
|
|
; RPU Type Parity: This routine checks to see if the RPU chip exists, and if so,
|
|
; enables parity interrupts and sets the parity bit in d7. The RPU operates correctly
|
|
; even if no SIMM's installed are parity SIMMs (parity is detected on the SIMM).
|
|
;-------------------------------------------------------------------------------
|
|
checkForParity
|
|
move.l a6,d4 ;save return address in d4
|
|
moveq.l #0,d2 ;prep d2 for universal call
|
|
BSR6 JGetHardwareInfo ;get info on this machine
|
|
|
|
bset #parity,d7 ;assume we have parity
|
|
bset #beok,d7 ;tell the bus error handler it's ok
|
|
movea.l sp,a5 ;copy sp for NMI handler
|
|
|
|
btst #ProductInfo.PGCInstalled,d1 ;see if we have a PGC chip <7>
|
|
beq.s @noPGC ;no, see if RPU type parity
|
|
|
|
move.l #PGCParity,d0 ;tell the NMI handler to expect PGC parity errors
|
|
movea.l VIA1Addr(a0),a2 ;get VIA1 base
|
|
bclr #vPGCEnb,VBufB(a2) ;enable PGC parity interrupts
|
|
tst.b VBufB(a2) ;access VIA to delay a little
|
|
|
|
lea @noPGCparity,a6 ;load up return address for NMI
|
|
movea.l (sp),a4 ;get base of chunk table <1.9>
|
|
@next movea.l (a4)+,a3 ;check at base of each bank <1.8>
|
|
cmpa.l #-1,a3 ;at end of table?
|
|
beq.s @scanParityRam ;(-1) means end of table
|
|
|
|
addq.l #4,a4 ;skip past size
|
|
move.l #$01010101,(a3) ;put one 1 on every SIMM (parity bit = 0)
|
|
tst.l (a3) ;parity error if no parity bit exists (floats to 1)
|
|
move.l #0,(a3) ;put zeros on all bits (parity bit = 1) <2.0>
|
|
tst.l (a3) ;parity error if no parity bit exists <2.0>
|
|
bra.s @next ;check next bank
|
|
|
|
@noPGCparity
|
|
bset #vPGCEnb,VBufB(a1) ;disable parity checking
|
|
bra.s @noParity
|
|
|
|
@noPGC
|
|
|
|
|
|
btst #RPUExists,d0 ;do we support RPU (F-19) parity?
|
|
beq.s @noParity ;no, then we don't support parity
|
|
|
|
move.l #RPUParity,d0 ;tell the NMI handler to expect RPU parity errors
|
|
movea.l RPUAddr(a0),a2 ;get OSS base
|
|
st.b rpuReset(a2) ;reset serial pointer
|
|
clr.b (a2) ;write good parity mode
|
|
st.b (a2) ;clear any parity errors caused by SizeMemory
|
|
movea.l OSSAddr(a0),a1 ;get OSS base
|
|
move.b #7,OSSMskRPU(a1) ;enable RPU parity interrupts (level 7)
|
|
|
|
@scanParityRam
|
|
lea @parityError,a6 ;an NMI will send us here
|
|
move.l (sp),a4 ;get base of chunk table
|
|
|
|
@nextBank
|
|
move.l (a4)+,a2 ;get start of bank
|
|
cmpa.l #-1,a2 ;no more banks?
|
|
beq.s @scandone ;yes, exit
|
|
move.l (a4)+,d5 ;get length
|
|
|
|
@check movem.l (a2)+,d1-d3/d6 ;test 16 bytes at a time <1.5>
|
|
subq.l #4,d5
|
|
bgt.s @check ;finish testing bank
|
|
bra.s @nextBank ;do next bank
|
|
|
|
@parityError
|
|
moveq.l #1,d6 ;indicate a parity error
|
|
bra.s @exit ;and exit
|
|
|
|
@noParity
|
|
bclr.l #parity,d7 ;clear parity ram installed bit
|
|
|
|
@scandone
|
|
moveq.l #0,d6 ;clear return status (no parity)
|
|
|
|
@exit bclr.l #beok,d7 ;normal operation again
|
|
moveq.l #0,d0 ;clear parity signature
|
|
movea.l d4,a6 ;restore return address
|
|
RTS6 ;return
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
|
|
JGetHardwareInfo
|
|
ori.w #hiIntMask,sr ;turn off interrupts <2.1>
|
|
|
|
IF forRomulator THEN ; <T9>
|
|
TestInRAM a0 ;are we in RAM <T9>
|
|
beq.s @inROM ;branch if we're in ROM <T9>
|
|
|
|
move.l a6,-(sp) ;save return address <T9>
|
|
|
|
movec vbr,a6 ;get the VBR <T9>
|
|
move.l BusErrVct(a6),-(sp) ;and save the bus error vector in our local space<T9>
|
|
|
|
lea @GotBusError,a0 ;get the address of our local bus error handler<T9>
|
|
move.l a0,BusErrVct(a6) ;move it on in there <T9>
|
|
|
|
bigbsr6 GetHardwareInfo,a0 ;call gethardware info <T9>
|
|
|
|
movec vbr,a6 ;get the vbr again <T9>
|
|
move.l (sp)+,BusErrVct(a6) ;restore the bus error handler <T9>
|
|
|
|
rts ;and return to caller <T9>
|
|
|
|
@GotBusError ; <T9>
|
|
btst.l #beok,d7 ; indicate that bus error occured <T9>
|
|
move.l a5,a7 ; restore stack <T9>
|
|
rts6 ; return <T9>
|
|
|
|
@inROM ; <T9>
|
|
ENDIF ; <T9>
|
|
|
|
BigJMP GetHardwareInfo,a0 ;make long bsr6 to actual routine
|
|
|
|
;------------------------------------------------------------------------
|
|
|
|
JGetExtHardwareInfo ; <MC3> SAM
|
|
ori.w #hiIntMask,sr ;turn off interrupts
|
|
|
|
IF forRomulator THEN ;
|
|
TestInRAM a0 ;are we in RAM
|
|
beq.s @inROM ;branch if we're in ROM
|
|
|
|
move.l a6,-(sp) ;save return address
|
|
|
|
movec vbr,a6 ;get the VBR
|
|
move.l BusErrVct(a6),-(sp) ;and save the bus error vector in our local space
|
|
|
|
lea @GotBusError,a0 ;get the address of our local bus error handler
|
|
move.l a0,BusErrVct(a6) ;move it on in there
|
|
|
|
bigbsr6 GetExtHardwareInfo,a0 ;call gethardware info
|
|
|
|
movec vbr,a6 ;get the vbr again
|
|
move.l (sp)+,BusErrVct(a6) ;restore the bus error handler
|
|
|
|
rts ;and return to caller
|
|
|
|
@GotBusError ;
|
|
btst.l #beok,d7 ; indicate that bus error occured
|
|
move.l a5,a7 ; restore stack
|
|
rts6 ; return
|
|
|
|
@inROM ;
|
|
ENDIF ;
|
|
|
|
BigJMP GetExtHardwareInfo,a0 ;make long bsr6 to actual routine
|
|
|
|
;------------------------------------------------------------------------
|
|
|
|
|
|
;
|
|
; The following routine sizes VRAM on V8 equiped Elsie machines. This routine must
|
|
; be called before using memory (even before sizing it and testing it). This is
|
|
; because the setting of the VRAM size bits affect how the RAM is ordered in the
|
|
; address space.
|
|
;
|
|
SizeV8VRAM
|
|
|
|
WITH ProductInfo, DecoderInfo
|
|
move.l ExtValid(a1),d0 ;get external features flag <SM17>
|
|
btst.l #V8ChipBit,d0 ;Is this a V8 machine (LC/LCII)? <SM17>
|
|
beq.s @Done ;If not V8 machine then we're finished <SM17>
|
|
|
|
movea.l RBVAddr(a0),a2 ;Get the RBV address <30>
|
|
move.l VideoInfoPtr(a1),d0 ;Get the video info pointer address offset <30>
|
|
movea.l (a1,d0.l),a0 ;and offset to the actual pointer <30>
|
|
ENDWITH ;ProductInfo, DecoderInfo
|
|
|
|
move.l #'Shel',d0 ;Get a signature <30>
|
|
moveq.l #-1,d1 ;and a bus discharger <30>
|
|
move.l #1<<18,d2 ;Store 256K into a register <30>
|
|
|
|
bset.b #V8vRAMIn,V8Exp(a2) ;Set the VRAM installed bit <30>
|
|
bset.b #V8512Row,V8Exp(a2) ;and set the 512 rowbytes (selects 256K of VRAM) <30>
|
|
|
|
move.l d0,(a0) ;store the signature into VRAM <30>
|
|
move.l d1,4(a0) ;now eliminate any stray bus charges <30>
|
|
cmp.l (a0,d2.l),d0 ;Look at offset 256K <30>
|
|
beq.s @Done ;If this is equal we have 256K of VRAM <30>
|
|
cmp.l (a0),d0 ;else see if there's any VRAM at all <30>
|
|
beq.s @512KVRAM ;Yes - we must have 512K of it <30>
|
|
bclr.b #V8vRAMIn,V8Exp(a2) ;Else, No VRAM installed, clear the appropriate bit <30>
|
|
bra.s @Done
|
|
|
|
@512KVRAM
|
|
bclr.b #V8512row,V8Exp(a2) ;512K of VRAM: clr the 512 rowbytes <30>
|
|
@Done
|
|
RTS6
|
|
|
|
;From here to the next <34> below was added to support the machine dependant test tables.
|
|
USTInit
|
|
;-------------------------------------------------------------------------------------
|
|
; This routine initializes all the information needed by the subtests. It returns in a5
|
|
; a pointer to a data structure with the following format (increasing addresses down):
|
|
;
|
|
; a5 -> WarmStartConstant
|
|
; +4h Product info pointer (long)
|
|
; +8h Bases valid flags (long)
|
|
; +Ch Chunk table (1 or more 2 long word entries)
|
|
; +Ch+8n FFFF FFFF
|
|
; where n = number of chunk table entries
|
|
;
|
|
; The format of this data structure is defined in the USTGlobals record.
|
|
;
|
|
|
|
; This routine initializes MOST OF the information needed by the subtests for the various ROM-based
|
|
; diagnostics environments (Startup/Restart, ROM BurnIn, In House Testers (board testers), Serial
|
|
; Test Manager, Test Manager ATrap). Specifically, it does set up everything needed by the RBI
|
|
; environment. Some of the others fill in the fields as necessary.
|
|
;
|
|
; The data structure that is created and initialized here is known as the USTGlobals. It contains
|
|
; information that the diagnostics environments need to keep around as they are executing DTMs and
|
|
; stuff.
|
|
;
|
|
; It returns in a5 a pointer to the data structure with the following format (increasing
|
|
; addresses up):
|
|
;
|
|
; NOTE: the fields marked with "*" indicate that they are initialized by this routine
|
|
; (some fields are used by other environments - IHT, STM, etc. - and are not needed
|
|
; by RBI, so they are left uninitialized, to be managed by the routine(s) that need them).
|
|
;
|
|
; NOTE 2: The USTGlobals structure has been enhanced for the Horror ROM (and all of its
|
|
; kin) to support the paramters to the GI_ExecuteDTM call, new for CTE v2.1.
|
|
;
|
|
;
|
|
; +92h+8n FFFF FFFF
|
|
; where n = number of chunk table entries
|
|
; * +8Eh Chunk table (1 or more 2 long word entries)
|
|
;
|
|
; ; These are the executionResults structure fields:
|
|
;
|
|
; +8Ah exResSubtestResults
|
|
; +86h exResSubtestParams
|
|
; +82h exResTestResults
|
|
; +7Eh exResTestParams
|
|
; +7Ah exResErr
|
|
;
|
|
;
|
|
; ; These are the subtestInfo structure fields:
|
|
;
|
|
; +76h sInfoResultsSize
|
|
; +72h sInfoParamsSize
|
|
; +6Eh sInfoFunctionEntry
|
|
; +6Ah sInfoID
|
|
; +66h sInfoUserInfo
|
|
;
|
|
;
|
|
; ; These are the testInfo structure fields:
|
|
;
|
|
; +62h tInfoResultsSize
|
|
; +5Eh tInfoParamsSize
|
|
; +5Ah tInfoFunctionEntry
|
|
; +56h tInfoID
|
|
; +52h tInfoUserInfo
|
|
;
|
|
;
|
|
; ; These are the executionOptions structure fields:
|
|
;
|
|
; +4Eh exOpIdleMethodArg
|
|
; +4Ah exOpIdleMethod
|
|
; +46h exOpSubtestResultsOverride
|
|
; +42h exOpSubtestParamsOverride
|
|
; +3Eh exOpTestResultsOverride
|
|
; +3Ah exOpTestParams
|
|
; +36h exOpExecutionMode
|
|
; +32h exOpProcessorType
|
|
; +2Eh exOpUserInfo
|
|
;
|
|
;
|
|
; ; These are the original USTGlobals from Terror (the Chunk Table has
|
|
; ; been moved to the end of the record, where it should stay):
|
|
;
|
|
; * +2Ah Bases valid flags (long)
|
|
; * +26h Product info pointer (long)
|
|
; * +22h Decoder info pointer
|
|
; * +1Eh WarmStartConstant
|
|
; +1Ah Pointer to an error handler (if any)
|
|
; +16h Pointer to the CTE globals
|
|
; * +12h Pointer to the CPU-specific test list in ROM
|
|
; +Eh Pointer to a list of subtests to execute (for CTE also)
|
|
; +Ah Pointer to a list of tests to execute (for CTE)
|
|
; +8h Run mode flags (startup, restart, etc.)
|
|
; +4h Size of the CTE command stack frame
|
|
; a5 ----> Current command number
|
|
; Vector table (copied into RAM by the SetVectorTable routine after the above
|
|
; structure is filled out). The vector table is copied from the ROM-based
|
|
; table declared at the beginning of this file. The VBR and SP point to the
|
|
; * VBR & SP --> base of this table.
|
|
;
|
|
;
|
|
;
|
|
; The format of this data structure (the one pointed to by a5, vector table not included)
|
|
; is defined in the USTGlobals record.
|
|
;
|
|
;
|
|
;
|
|
; Input:
|
|
; d2 - Flag. Clear: Call SizeMem at init. Set: Do NOT call SizeMem. <SM32>
|
|
;
|
|
; output:
|
|
; a5 - points to the standard environment data structure
|
|
; sp - initialized
|
|
;
|
|
; destroys most, if not all registers
|
|
;
|
|
; Called by: BSR6
|
|
;
|
|
;-------------------------------------------------------------------------------------
|
|
|
|
WITH USTGlobals, StartGlobals, CPUList, ProductInfo ; <36> <SM11> CSS
|
|
|
|
movea.l a6,a4 ;save the return address <SM3> rb, start
|
|
tst.b d2 ;is this a normal boot? (ie no diag ROM, serial test, etc.)? <SM32>
|
|
bne.s @noSize ;-> Yes. Do NOT call sizemem *again*! <SM32>
|
|
BSR6 SizeMemory ;Create the chunk table (relocates the stack)
|
|
@noSize moveq.l #0,d2 ;then get hardware information for this machine
|
|
BSR6 JGetHardwareInfo ;assume we know nothing
|
|
|
|
movea.l (sp),a2 ;get a pointer to the chunk table
|
|
|
|
movea.l (a2),a5 ;get a pointer to the base of a chunk <T14>
|
|
adda.l #(1<<16),a5 ;offset to end of second 32K <T14>
|
|
suba.w #sizeofUSTGlobals,a5 ;allocate space for our globals <T14>
|
|
move.l a2,ChunkTable(a5) ;put the pointer to the chunk table there <T14>
|
|
movea.l a5,sp ;and put the stack there <T14>
|
|
|
|
move.l sgWarmStart(a2),WarmStartConst(a5) ;remember the warm start constant <T14> <SM11> CSS
|
|
|
|
move.l d0,BasesValidFlags(a5) ;save the bases valid flags
|
|
move.l a1,PrdctInfPtr(a5) ;and a pointer to the product info record
|
|
move.l a0,DcdrInfPtr(a5) ;and a pointer to the decoder info record
|
|
|
|
move.b ProductKind(a1),d0 ;and get the box flag <36>
|
|
lea.l USTCPUList,a0 ;start at the beginning of the list of tables <36>
|
|
move.l a0,d2 ;save this for later <36>
|
|
|
|
@itemloop
|
|
move.w cpuBoxFlag(a0),d1 ;Get the box flag for this test table <36>
|
|
cmp.b #boxUnknown,d1 ;Is this the end of the table? <36>
|
|
beq.s @found ;quit if so - we'll use the default tests <36>
|
|
cmp.b d1,d0 ;is this the table entry for this machine? <36>
|
|
beq.s @found ;quit if so <36>
|
|
addq.l #sizeofCPUList,a0 ;else, go to the next table entry <36>
|
|
bra.s @itemloop ;and keep looking <36>
|
|
|
|
@found
|
|
movea.l CPUTestListPtr(a0),a0 ;get a pointer to the test table for this CPU <36>
|
|
lea.l (a0,d2.l),a0 ;and dereference it <36>
|
|
move.l a0,GlobCPUTestList(a5) ;and store it in the globals area. <36>
|
|
|
|
suba.l #VTEntries*4,sp ;get a vector table space in RAM
|
|
movea.l sp,a1 ;point a1 at it
|
|
BSR6 SetVectorTable ;then, set up our exception table in RAM
|
|
|
|
jmp (a4) ;and return to caller
|
|
|
|
ENDWITH
|
|
|
|
|
|
EXPORT USTGetSubtest
|
|
USTGetSubtest
|
|
;-------------------------------------------------------------------------------------
|
|
;
|
|
; This routine looks up a subtest ID in the master list of subtests and relocates the
|
|
; CTE information about the test into RAM.
|
|
;
|
|
; Input: The following information on the stack:
|
|
|
|
StackFrame1 RECORD 4, Increment ;start with offset for a saved register
|
|
|
|
return ds.l 1 ;Return address
|
|
ID ds.l 1 ;subtest ID
|
|
infoPtr ds.l 1 ;place to put the subtest info
|
|
|
|
ENDR
|
|
|
|
;
|
|
; Output:
|
|
; a0 - pointer to the subtest table for this CPU
|
|
;
|
|
; Destroys:
|
|
; d0, d1
|
|
;
|
|
;
|
|
; Called by: bsr
|
|
;
|
|
;-------------------------------------------------------------------------------------
|
|
|
|
WITH StackFrame1, USTSubtest
|
|
|
|
link a0,#0 ;save a0 and point it to the stack frame
|
|
movem.l a1/a2/d0/d1,-(sp) ;save some regs
|
|
|
|
lea.l USTSubtests,a1 ;get a pointer to the subtest table in ROM
|
|
move.l a1,d1 ;save it for later
|
|
move.l ID(a0),d0 ;get the test ID
|
|
@searchLoop
|
|
cmp.l STSubtest_ID(a1),d0 ;is this our test? <T12>
|
|
beq.s @load ;go load it if so
|
|
adda.w #sizeofUSTSubtest,a1 ;else get next test
|
|
bra.s @searchLoop ;and continue
|
|
@load
|
|
moveq.l #(sizeofUSTSubtest>>2)-1,d0 ;get size of subtest in long words
|
|
movea.l infoPtr(a0),a2 ;get the pointer to the storage area
|
|
@loadLoop
|
|
move.l (a1)+,(a2)+ ;move the data into the RAM area
|
|
dbra.w d0,@loadLoop
|
|
|
|
movea.l infoPtr(a0),a2 ;get the pointer to the storage area again
|
|
add.l d1,STEntryPtr(a2) ;dereference the entry pointer <T12>
|
|
add.l d1,STNamePtr(a2) ;and the name pointer <T12>
|
|
ENDWITH
|
|
|
|
movem.l (sp)+,a1/a2/d0/d1 ;restore some regs
|
|
unlk a0 ;get rid of our local storage <SM3> rb, end
|
|
rts
|
|
|
|
|
|
|
|
;_______________________________________________________________________
|
|
; USTPmgrTurnOn
|
|
;
|
|
; Written by: Scott Smyers 11/90
|
|
;
|
|
; This routine sends a command to the power manager. It requires the
|
|
; following information:
|
|
;
|
|
; a0- Decoder info pointer
|
|
; a6- return address
|
|
;
|
|
; register usage:
|
|
;
|
|
; a2- destroyed
|
|
; a3- destroyed
|
|
; a5- destroyed
|
|
; d3- destroyed
|
|
; d4- destroyed
|
|
;
|
|
; d6- status:
|
|
; 0 - success
|
|
; 1 - PMGR not ready
|
|
; 2 - PMGR timeout during handshake
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
USTPmgrTurnOn
|
|
MOVE.L DefExtFeatures(A0),D3 ; get the external features flags <H6>
|
|
BTST #ProductInfo.MSCChipBit,D3 ; are we on an MSC-based system? <H6>
|
|
BEQ.S @NoMSC ; -> nope, continue <H6>
|
|
MOVEA.L RBVAddr(A0),A2 ; point to the base of the MSC <H6>
|
|
BSET #MSCSCCClk,MSCClkCntl(A2) ; turn on SCC clock (PMGR doesn't <H6>
|
|
@NoMSC ; control SCC in our case) <H6>
|
|
|
|
MOVE.L #((iwmOn|sccOn|serOn|ascOn)<<16)+\ ; data = what to turn on <H2>
|
|
(1<<8)+\ ; length = 1 <H2>
|
|
(powerCntl<<0),D3 ; command = power control <H2>
|
|
; BRA USTPMgrSendCommand ; send the command <H2>
|
|
|
|
|
|
;_______________________________________________________________________ <H2>
|
|
;
|
|
; USTPMGRSendCommand - sends a command and 0-2 data bytes to the PMGR.
|
|
;
|
|
; This routine is generally used for fixed-length commands, however
|
|
; by passing in a negative number for the length, it will exit after
|
|
; sending the command byte, permitting the true length byte to be sent.
|
|
;
|
|
; Inputs:
|
|
;
|
|
; D3- [data2] [data1] [length] [command]
|
|
; A0- pointer to DecoderInfo
|
|
; A6- return address
|
|
;
|
|
; Outputs:
|
|
;
|
|
; D6- result:
|
|
; 0 - success
|
|
; 1 - PMGR not ready
|
|
; 2 - PMGR timeout during handshake
|
|
;
|
|
; Uses:
|
|
;
|
|
; D3- gets trashed
|
|
; D4- timeout counter from USTPMGRSendByte; bit 31=1 if serial interface,new protocol
|
|
; A2- base address of VIA1
|
|
; A3- base address of VIA2
|
|
; A5- return address
|
|
;_______________________________________________________________________
|
|
|
|
PMack EQU v2PMack
|
|
PMreq EQU v2PMreq
|
|
PMbuf EQU vBufAH
|
|
PMbufDir EQU vDirA
|
|
|
|
USTPMGRSendCommand
|
|
WITH DecoderInfo,ProductInfo
|
|
MOVEA.L VIA1Addr(A0),A2 ; point to the base of VIA1
|
|
MOVE.L VIA2Addr(A0),D6 ; and VIA2 <H8>
|
|
BNE.S @HaveVIA2 ; -> VIA2 exists
|
|
MOVE.L RBVAddr(A0),D6 ; otherwise use the RBV look-alike <H8>
|
|
@HaveVIA2 MOVEA.L D6,A3 ; <H8>
|
|
ENDWITH
|
|
|
|
MOVEQ #1,D6 ; assume pmgr not ready
|
|
MOVE.W #32*nTicks,D4 ; use 32ms timeout (based on VIA access)
|
|
@WaitAckHi TST.B (A2) ; (throttle execution speed with a VIA access) <H3>
|
|
BTST.B #PMack,(A3) ; wait for /ack to go high
|
|
DBNE D4,@WaitAckHi ; -> keep waiting
|
|
BEQ.S @Done ; -> timed out
|
|
|
|
BSR5 USTPMGRSendByte ; send the command byte
|
|
BNE.S @Done ; -> timed out <H3>
|
|
|
|
ASR.W #8,D3 ; shift the length into the next position <H8>
|
|
BMI.S @Done ; -> variable length command: bail now <H8>
|
|
TST.L D4 ; do we need to send the length?
|
|
BMI.S @NoLength
|
|
BSR5 USTPMGRSendByte ; yes, send it
|
|
BNE.S @Done ; -> timed out <H3>
|
|
|
|
@NoLength SUBQ.B #1,D3 ; any data?
|
|
BMI.S @Done ; -> no, done
|
|
SWAP D3 ; get the first data byte
|
|
BSR5 USTPMGRSendByte ; and send it
|
|
BNE.S @Done ; -> timed out <H3>
|
|
SWAP D3 ; get the count back
|
|
|
|
SUBQ.B #1,D3 ; any data?
|
|
BMI.S @Done ; -> no, done
|
|
SWAP D3 ; get the second data byte,
|
|
LSR.W #8,D3 ; shift it into position,
|
|
BSR5 USTPMGRSendByte ; and send it
|
|
|
|
@Done TST.L D6 ; set up the CCR <H3>
|
|
RTS6
|
|
|
|
|
|
ReadPramSig
|
|
;_______________________________________________________________________
|
|
;
|
|
; ReadPramSig - Universal Start Test read 4 byte signature from parameter RAM
|
|
;
|
|
; Written by: Scott Smyers 2/91
|
|
;
|
|
; This routine reads a 4 byte signature from parameter RAM. It requires the
|
|
; following information:
|
|
;
|
|
; a1- base address of ProductInfo record
|
|
; a2- VIA1 base address
|
|
; a6- return address
|
|
;
|
|
; d3.w- PRAM start address of 4 byte signature - must be on a long word boundary
|
|
; (i.e., low order 2 bits must be zero)
|
|
;
|
|
; registers destroyed:
|
|
; d0-2/d5, a3-6 and the low word of d3
|
|
;
|
|
; Output:
|
|
; d4 - contains the long word signature
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
|
|
move.l a6,d5 ;save the return address
|
|
|
|
@next move.w d3,d1 ;d1 = address to read from Pram <v1.1><7><9>
|
|
BSR6 RdXByte ;go read the byte <v1.1><7><9>
|
|
rol.l #8,d4 ;Accumulate signature bytes in D4 <7><9>
|
|
move.b d1,d4 ; <7><9>
|
|
addq.w #1,d3 ;increase by one <v1.1><7><9>
|
|
move.w d3,d1 ;See if we've read all the signature bytes <9>
|
|
and.w #$03,d1 ;low nibble will wrap if so <9>
|
|
bne.s @next ;Continue if not <7><9>
|
|
|
|
movea.l d5,a6
|
|
RTS6
|
|
|
|
USTPMGRSendByte
|
|
;_______________________________________________________________________
|
|
;
|
|
; USTPMGRSendByte - Universal Start Test Power Manager Send Byte
|
|
;
|
|
; Written by: Scott Smyers 11/90
|
|
;
|
|
; This routine sends a single byte to the power manager. It requires the
|
|
; following information:
|
|
;
|
|
; a0- pointer to decoder info <H2>
|
|
; a2- base address of VIA1 <H2>
|
|
; a3- base address of VIA2
|
|
; a5- return address
|
|
; d3- byte to send to the pmgr
|
|
;
|
|
; register usage:
|
|
;
|
|
; d4- destroyed, but bit 31=1 if new (serial) interface, else bit 31=0
|
|
;
|
|
; d6- status:
|
|
; 0 - success
|
|
; 2 - PMGR timeout during handshake
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
move.w #32*nTicks,d4 ; 32ms timeout <H8>
|
|
BCLR #31,D4 ; clear the serial flag <H8>
|
|
WITH ProductInfo ; <H2>
|
|
BTST #PMgrNewIntf//8,DefExtFeatures+3-(PMgrNewIntf/8)(A0)
|
|
; parallel interface? <H2>
|
|
ENDWITH ; <H2>
|
|
BEQ.S @IsParallel ; -> yes <H2>
|
|
MOVEA.L RBVAddr(A0),A3 ; serial interface is in a RBV look-alike <H2>
|
|
BSET #31,D4 ; mark this as a serial interface <H2>
|
|
BSET #4,vACR(A2) ; set shift register to shift out under ext clock <H2>
|
|
MOVE.B D3,vSR(A2) ; write out the byte to the shift register <H2>
|
|
BRA.S @DropReq ; <H2>
|
|
|
|
@IsParallel ; <H2>
|
|
move.b #$FF,PMbufDir(a3) ;Make VIA port an output
|
|
move.b d3,PMbuf(a3) ;put the data byte on the bus
|
|
|
|
@DropReq ; <H2>
|
|
moveq.l #2,d6 ;assume pmgr timeout error
|
|
|
|
bclr.b #PMreq,(a3) ;lower the request line
|
|
|
|
@ackOn
|
|
TST.B (A2) ; (throttle execution speed with a VIA access) <H2>
|
|
btst.b #PMack,(a3) ;wait for ack to go low
|
|
dbeq.w d4,@ackOn ;loop until timeout or ack
|
|
bne.s @Error ;error out if timeout
|
|
|
|
move.w #nTicks/8,d4 ; use 125usec timeout <H2>
|
|
bset.b #PMreq,(a3) ;turn off request line
|
|
|
|
@ackOff
|
|
TST.B (A2) ; (throttle execution speed with a VIA access) <H2>
|
|
btst.b #PMack,(a3) ;wait for ack to go high
|
|
dbne.w d4,@ackOff ;keep going until high or timeout
|
|
beq.s @Error ;error out if timeout (ack still low)
|
|
|
|
moveq.l #0,d6 ;all's well
|
|
@Error
|
|
bset #PMreq,(a3) ;turn off request line
|
|
|
|
TST.L D4 ; serial interface? <H2>
|
|
BMI.S @IsSerial ; -> yes, don't touch port A stuff <H2>
|
|
move.b #0,PMBufDir(a3) ;make port an input
|
|
@IsSerial ; <H2>
|
|
tst.l d6 ;return with state of d6 in the Z bit
|
|
RTS5 ;and return
|
|
|
|
|
|
;_______________________________________________________________________ <H3>
|
|
;
|
|
; USTPMGRRecvByte - Universal Start Test Power Manager Receive Byte
|
|
;
|
|
; This routine receives a single byte from the power manager.
|
|
; It requires the following information:
|
|
;
|
|
; A0- pointer to decoder info
|
|
; A2- base address of VIA1
|
|
; A3- base address of VIA2
|
|
; A5- return address
|
|
; D3- byte to send to the pmgr
|
|
;
|
|
; register usage:
|
|
;
|
|
; D4- destroyed, but bit 31=1 if new (serial) interface, else bit 31=0
|
|
;
|
|
; D6- status:
|
|
; 0 - success
|
|
; 2 - PMGR timeout during handshake
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
USTPMGRRecvByte
|
|
MOVEQ #2,D6 ; assume PMGR timeout
|
|
move.w #32*nTicks,d4 ; 32ms timeout <H8>
|
|
BCLR #31,D4 ; clear serial flag (bit 31) <H8>
|
|
WITH ProductInfo
|
|
BTST #PMgrNewIntf//8,DefExtFeatures+3-(PMgrNewIntf/8)(A0)
|
|
; parallel interface?
|
|
ENDWITH
|
|
BEQ.S @IsParallel ; -> yes
|
|
MOVE.L VIA2Addr(A0),D6 ; and VIA2 <K5>
|
|
BNE.S @HaveVIA2 ; -> VIA2 exists
|
|
MOVE.L RBVAddr(A0),D6 ; otherwise use the RBV look-alike <K5>
|
|
@HaveVIA2
|
|
MOVEA.L D6,A3 ; <K5>
|
|
BSET #31,D4 ; mark this as a serial interface
|
|
|
|
MOVE.B vACR(A2),D4 ; set shift register to shift in under external clock
|
|
AND.B #$EF,D4
|
|
ORI.B #%00001100,D4 ; set up shift register
|
|
MOVE.B D4,vACR(A2) ; set up shift register
|
|
|
|
TST.B vSR(A2) ; read a byte to reset the shifter
|
|
|
|
BCLR #PMreq,(A3) ; assert /req to start the handshake
|
|
|
|
@Wait4AckLo TST.B (A2) ; (throttle execution speed with a VIA access)
|
|
BTST #PMack,(A3) ; wait for /ack to go low
|
|
DBEQ D4,@Wait4AckLo ; -> loop until timeout or ack
|
|
BNE.S @Error ; -> timed out
|
|
|
|
BSET #PMreq,(A3) ; de-assert /req since we've seen /ack asserted
|
|
|
|
MOVE.W #nTicks/8,D4 ; use 125usec timeout
|
|
@Wait4AckHi TST.B (A2) ; (throttle execution speed with a VIA access)
|
|
BTST #PMack,(A3) ; wait for /ack to go high
|
|
DBNE D4,@Wait4AckHi ; -> loop until timeout or ack
|
|
BEQ.S @Error ; -> timed out
|
|
|
|
MOVE.B vSR(A2),D3 ; read in the byte
|
|
BRA.S @Success
|
|
|
|
|
|
@IsParallel MOVE.B #$00,PMBufDir(A3) ; make the data port an input
|
|
|
|
@AckOn TST.B (A2) ; (throttle execution speed with a VIA access)
|
|
BTST #PMack,(A3) ; wait for /ack to go low
|
|
DBEQ D4,@AckOn ; -> loop until timeout or ack
|
|
BNE.S @Error ; -> timed out
|
|
|
|
BCLR #PMreq,(A3) ; assert the /req line
|
|
|
|
MOVE.B PMbuf(A3),D3 ; read in the byte
|
|
|
|
MOVE.W #nTicks/8,D4 ; use 125usec timeout
|
|
@AckOff TST.B (A2) ; (throttle execution speed with a VIA access)
|
|
BTST #PMack,(A3) ; wait for /ack to go high
|
|
DBNE D4,@AckOff ; -> loop until timeout or ack
|
|
BEQ.S @Error ; -> timed out
|
|
|
|
@Success MOVEQ #0,D6 ; success!
|
|
|
|
@Error BSET #PMreq,(A3) ; be sure /req is not asserted
|
|
TST.L D4 ; serial or parallel interface?
|
|
BMI.S @IsSerial
|
|
MOVE.B #0,PMBufDir(A2) ; switch the data port back to an input
|
|
BRA.S @Done
|
|
|
|
@IsSerial ORI.B #%00011100,vACR(A1) ; make the shift register shift out <K5>
|
|
@Done TST.L D6 ; return with BEQ for no error, BNE for error
|
|
RTS5
|
|
|
|
|
|
;
|
|
; This is the list of machines which were introduced after the macLC
|
|
; which have a factory edge connector. For these machines, the test
|
|
; of the burnin jumper is still performed.
|
|
;
|
|
|
|
PostLC_BIJumper_boxes
|
|
dc.b boxQuadra900
|
|
dc.b boxQuadra700
|
|
dc.b boxClassicII ; <SM9> CSS
|
|
dc.b boxQuadra950 ; <Z15><H5>
|
|
dc.b boxMacLCII ; <SM17>
|
|
dc.b boxUnknown ;table terminator
|
|
|
|
;________________________________________________________________________________________ <MC3>
|
|
;
|
|
; Routine: NuBusReset
|
|
;
|
|
; Inputs: a0 Pointer to DecoderInfo record for this machine
|
|
; d0 Flags indicating which base addresses are valid #32-63
|
|
; Outputs: ...
|
|
;
|
|
; Trashes: Tons of stuff.
|
|
;
|
|
; Function: If we have a BART NuBus controller, tell it to pulse the NuBus reset (1ms).
|
|
; This is needed because on a soft restart, the NuBus reset line doesn't get
|
|
; asserted.
|
|
;________________________________________________________________________________________
|
|
|
|
NuBusReset
|
|
WITH DecoderInfo
|
|
|
|
btst #BARTExists-32,d0 ; do we have BART?
|
|
beq.s @exit
|
|
|
|
move.l BARTAddr(a0),a0 ; get address of BART
|
|
move.b #$80,(a0) ; drive reset
|
|
|
|
BigBSR6 GetCPUIDReg ; Get the CPU id
|
|
cmpi.w #$3011,D0 ; Is this a single slot PDM-style machine w/bart?
|
|
beq.s @exit ; -> Yes, do not disable the only real slot we have!
|
|
|
|
move.b #$80,$11(a0) ; Disable slot E irqs from BART
|
|
|
|
@exit RTS5 ; and return
|
|
|
|
|
|
|
|
;________________________________________________________________________________________ <MC6>
|
|
;
|
|
; Routine: BSR5 PDS_Reset
|
|
;
|
|
; Inputs: vbr setup for bus-error
|
|
; Outputs: none
|
|
;
|
|
; Trashes: d0-d1,a0-a1,a6
|
|
;
|
|
; Function: This code will check the DECL ROM for a signature indicating an HPV or Planaria
|
|
; card (or even a third party card). If one exists, it will hit the hardware to
|
|
; simulate a card reset, so we don't leave video hanging around until PrimaryInit
|
|
; time. The routine is hard coded for Slot E, and assumes 1 byte lane cards.
|
|
;
|
|
; This signature is located 64 bytes from the end of the ROM, and is followed by
|
|
; an 8 byte address (the register to hit), then by a single byte to write to that
|
|
; address:
|
|
;
|
|
; For example, suppose that the 'reset' address is $fec00043, and we want to write
|
|
; a $07 there. Then starting at address $1ffc0 of a 128k byte config ROM, we would
|
|
; place the following data:
|
|
;
|
|
; $1ffc0: dc.l $56696452
|
|
; dc.l $65736574
|
|
; dc.l $fec00043
|
|
; dc.b $07
|
|
;________________________________________________________________________________________
|
|
DeclSigAddr EQU $feffff00 ; location of the signature (assumes 1 byte lane, lane 3)
|
|
|
|
WITH ProductInfo
|
|
|
|
PDS_Reset
|
|
cmp.b #HMCDecoder, DecoderKind(a1) ; are we a PDM?
|
|
bne.s @exit ; no, do nothing
|
|
|
|
move.l a5,d0 ; save return address
|
|
bset #beok,d7 ; we're expecting a bus error potentially
|
|
move.l sp,a5 ; save stack pointer
|
|
lea @busErr,a6 ; load return address (in case we take the bus error)
|
|
tst.l DeclSigAddr ; first, see if we can access the PDS slot (slot E)?
|
|
move.l d0,a5 ; restore return address
|
|
|
|
lea DeclSigAddr,a0 ; get address at end of DeclROM where signature lives
|
|
lea ResetSignature,a1 ; second, check for the signature
|
|
moveq #8-1,d1
|
|
@loop move.b (a0),d0 ; get next byte from DECL ROM
|
|
addq.l #4,a0
|
|
cmp.b (a1)+,d0 ; does it match?
|
|
dbne d1,@loop ; yes, check rest of signature
|
|
bne.s @exit ; no, exit
|
|
moveq #4-1,d1 ; signature matched, get next 4 bytes to form address
|
|
@addrLoop lsl.l #8,d0 ; make room for next byte of address
|
|
move.b (a0),d0 ; get next byte
|
|
addq.l #4,a0 ; bump to next position in DECL ROM
|
|
dbra d1,@addrLoop
|
|
move.l d0,a1 ; get complete address
|
|
|
|
move.b (a0),(a1) ; write the following byte to that address (to reset the card)
|
|
bra.s @exit ; and we're done
|
|
|
|
@busErr movea.l d0,a5 ; restore return address
|
|
@exit RTS5
|
|
|
|
ENDWITH
|
|
|
|
ResetSignature
|
|
dc.l $56696452
|
|
dc.l $65736574
|
|
|
|
|
|
|
|
|
|
|
|
ENDPROC
|