mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-22 08:30:05 +00:00
2130 lines
91 KiB
Plaintext
2130 lines
91 KiB
Plaintext
;__________________________________________________________________________________________________
|
|
;
|
|
; File: Universal.a
|
|
;
|
|
; Contains: This module provides Data structures and routines to support Universal ROMs.
|
|
; It can also be used in Non-Universal ROMs to provide tables for initializing
|
|
; base addresses and hardware.
|
|
;
|
|
; Written by: Gary G. Davidian
|
|
;
|
|
; Copyright © 1989-1993 by Apple Computer, Inc. All rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM62> 12/17/93 PN Fix the test for Pratt decoder
|
|
; <SM61> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
|
; machines.
|
|
; <SM60> 12/7/93 BG Modified the Frigidaire entries in the djMEMC @MachineTbl to
|
|
; properly reflect the VIA PortA values for CPU ID+Speed.
|
|
; <SM59> 11/17/93 KW forSTP601 in GetCPUIDReg to or in Risc product to the id.
|
|
; <SM58> 11/9/93 KW made some changes for STP machines. changes are conditionalized
|
|
; by forSTP601
|
|
; <SM57> 9/26/93 KW (H35 BG) Modified the djMEMC memory controller setup so that it
|
|
; chooses between Wombats and Speedbumped Wombats and initializes
|
|
; the memory controller to use a different set of wait states for
|
|
; the Speedbumped machines. This is because the Speedbump'ed
|
|
; units do not want to have to use faster-speed DRAM, which
|
|
; currently the Quadra 800 (Wombat33inFridge) requires. The
|
|
; Speedbumped 650 (Wombat33inLego) will expect 80ns DRAM, just as
|
|
; the Centris650 (Wombat25inLego) did.
|
|
; <SM56> 8/13/93 KW adding two more smurf wombats
|
|
; <SM55> 8/12/93 BG Changed various Cyclone-related boxflags to their official
|
|
; names.
|
|
; <SM54> 8/11/93 KW made the forSmurf check in GetCPUIDReg dynamic. Currently
|
|
; recoginizes Quadra700/900/950 and Centris610/650 quadra800
|
|
; <SM53> 7/27/93 GMR Added routine to do a runtime check for BART (on PDM).
|
|
; <SM52> 7/2/93 PN Add conditional for export hasCPUIDregs
|
|
; <SM51> 6/29/93 SAM (PDW) Added code to check for a cf96 in GetCPUID (for
|
|
; PDM/ColdFusion).
|
|
; <SM50> 6/14/93 kc Roll in Ludwig.
|
|
; <LW7> 4/29/93 fau Updated the Cyclone/Tempest timing to 120ns ROMS for final
|
|
; shipment.
|
|
; <SM49> 6/3/93 SAM Exporting GetCPUIDReg.
|
|
; <SM48> 5/10/93 SAM Added a few nops in the PDM specific CPU ID check.
|
|
; <SM46> 4/26/93 RC Get ride of warning due to bra.s
|
|
; <SM45> 4/21/93 joe Added hack to GetCPUIDReg for PDM EVT2. (CPUID register doesn't
|
|
; work right, so use extra bits in SCSI DMA Ctl reg to check for
|
|
; AMIC2.)
|
|
; <SM44> 4/20/93 joe Added to PDM-style CPUID reg check. The old
|
|
; long-word-access-only code would read the register, write some
|
|
; value back, and re-read the register, making sure that the
|
|
; second read yielded the same data as the first. The PDM-style,
|
|
; byte-access CPUID register read code now does this too.
|
|
; <SM43> 4/20/93 jb Fixed up the code to work on either a normal or PDM-style CPUID
|
|
; register.
|
|
; <SM42> 3/31/93 chp Synchronize SuperMario with changes from <LW5>.
|
|
; <LW5> 2/26/93 fau Removed support for Cyclone EVT3 and changed all labels having
|
|
; MMC with YMCA.
|
|
; <SM41> 2/23/93 RB Fixed a check for djMEMC in InitVIAs where it was depending on
|
|
; d3 which wasn't set up. Now checking decoder kind in the low
|
|
; byte of d2.
|
|
; <SM40> 2/8/93 rab Rolled in the following change from Horror for Wombat: <H30>
|
|
; 11/18/92 BG Modified TestForSonic so that instead of just
|
|
; reading a register at SonicBase to determine if Sonic is
|
|
; present, we actually WRITE a SW Reset command to Sonic. This
|
|
; way, not only do we detect it, but we make sure Sonic is always
|
|
; reset when booting/restarting.
|
|
; <SM39> 1/15/93 PN In case of Quadra 900 which has a Caboose chip, we do not
|
|
; execute the DoEgretInit but do a CudaDone otherwise we kill
|
|
; Quadra900.
|
|
; <SM38> 01/09/93 RM/HY Disable asynchronous messages on Egret based machines. This
|
|
; fixes a problem which could potentially causes hangs to occurr
|
|
; on restart if enough time elapses before Egret can respond to
|
|
; these messages.
|
|
; <SM37> 12/23/92 RC Added Support for Smurf on Wombat
|
|
; <SM36> 12/17/92 RB Removed some of the LC930 conditionals. Added back other hasXXXX
|
|
; conditionals to make it easier to build 1 off 1 Meg ROMs.
|
|
; <SM35> 12/11/92 FU Was always checking BoxCyclone33 when programming the YMCA.
|
|
; <SM34> 12/4/92 fau Added support for Cyclone40 and Tempest33.
|
|
; <SM33> 11/20/92 fau Didn't put a ; on one of my comments.
|
|
; <SM32> 11/20/92 fau Added a TestForMUNI to GetExtHardwareInfo so that Tempest can
|
|
; check whether the Nubus adapter is there or not. Programmed
|
|
; MUNI for Tempest.
|
|
; <SM31> 11/7/92 rab Roll in Horror changes. Comments follow:
|
|
; <H29> 8/10/92 SWC Fixed the MSC VIA/RBV initialization to disable slot interrupts.
|
|
; <H28> 7/2/92 ag Change initial state of the Jaws/dart via2 modemRst bit. It
|
|
; should be 0 to insure the modem is in reset when not in use.
|
|
; This also avoids current leakage to the modem.
|
|
; <H27> 6/25/92 CCH Added conditionalized support for Quadra on RISC-based emulator.
|
|
; <H26> 6/4/92 HY Add ptr to sound primitives vector table in LC product info table.
|
|
; <H25> 6/3/92 BG Conditionally changed -InitVIAs- temporarily to build the
|
|
; correct sequence of code for the BIOS1 chip on Wombat til BIOS
|
|
; is revved to have VIA1 work correctly. This change only takes
|
|
; effect if you Build -p -WombatEVT1.
|
|
; <H24> 5/28/92 NJV Added SoundPlayAndRecord bit to ProductInfo Tables of machines
|
|
; that can play and record simultaneously.
|
|
; <H22> 05-18-92 jmp Changed the ÒsRsrcZydecoDirÓ name to the more generic
|
|
; ÒsRsrcBFBasedDirÓ (BF=BoxFlag) name.
|
|
; <H18> 5/3/92 BG Removed references to hasOrwell2, since it is now superfluous to
|
|
; hasOrwell.
|
|
; <H17> 4/24/92 HJR Added CheckForNiagra so that we may distinguish from
|
|
; Jawsdecoder.
|
|
; <SM30> 11/3/92 SWC Changed SlotEqu.a->Slots.a.
|
|
; <SM29> 11/2/92 kc Make change to prevent unwanted branch island (to data).
|
|
; <SM28> 10/27/92 fau Rolled in a Horror patch for TestForFPU that also works for
|
|
; 040's without and FPU. This is to support Tempest. Added the
|
|
; necessary changes to the programming of the YMCA for Tempest.
|
|
; <SM27> 10/25/92 HY Add code in jumpintoRom to turn on & grey LC/LC II screen early.
|
|
; <SM26> 10/20/92 fau Stopped using "MMC/YMCAexists" and replaced by either comparing
|
|
; against DecoderKind or by using PSCexists. Also, changed
|
|
; YMCAAddr/MMCAddr to use DecoderAddr.
|
|
; <SM25> 10/18/92 CCH Added support for PDM and conditionalized support for Smurf.
|
|
; <SM24> 10/12/92 RB For the 1 Meg LC930 ROM, exclude all code not related to the LC
|
|
; hardware.
|
|
; <SM23> 9/30/92 fau Added support for Cyclone EVT4. This involved new DRAM/ROM
|
|
; speed values and a modification to GetHardwareInfo so that it
|
|
; looks at the CycloneEVT4 product info.
|
|
; <SM22> 9/25/92 RB Excluded some functions such as INITVias from executing while
|
|
; booting from RAM. Added a ROM base for the LC 2. Hacked
|
|
; GetCPUIDReg to return Cyclone when ROMinRAM testing.
|
|
; <SM21> 8/27/92 CCH Removed some now obsolete conditionals for Smurf card.
|
|
; <SM20> 8/25/92 chp Fix assembler warning.
|
|
; <SM19> 8/24/92 PN Take out CycloneboxEVT1
|
|
; <SM18> 8/20/92 CCH Don't initialize Orwell when running on a Cub Card.
|
|
; <SM17> 8/17/92 CCH Extended Universal support to 96-bits, added GetExtHardwareInfo
|
|
; routine to provide dynamic checking for feature existence.
|
|
; <SM16> 08-11-92 jmp Fixed a problem in the GetCPUIDReg routine where the CACR was
|
|
; being trashed; this caused Õ030 machines to die before BootBeep.
|
|
; <SM15> 8/9/92 CCH Removed uneeded conditionals and temporarily return a CPU ID
|
|
; for RISC cards.
|
|
; <SM14> 7/28/92 fau Corrected the Cyclone MMC_DRAMspeed0/1 to point to a 25MHz CPU
|
|
; with 60ns DRAM, instead of 25MHz with 80ns DRAM.
|
|
; <SM13> 7/21/92 kc Fix duplicate lable.
|
|
; <SM12> 7/13/92 CCH Added conditionalized support for Cub Card.
|
|
; <SM11> 6/30/92 kc Fix bug introduced with last checkin (trashing d0).
|
|
; <SM10> 6/26/92 GS (RBM) Add call to CudaInit to perform a SyncAck cycle prior to
|
|
; any transaction with Cuda. This will disable all asynchronous
|
|
; message sources within Cuda and will prevent any collisions from
|
|
; occuring in the low level io primitive routines prior to
|
|
; installation of the Cuda manager.
|
|
; <SM9> 6/21/92 RB ¥ Added a temporary check for EVT1 Cyclone in InitVIAs and
|
|
; CheckBases so that we don't have to support two builds for the
|
|
; next few weeks.
|
|
; <SM8> 6/9/92 kc Roll in Horror change from UniversalPatch.a,14.
|
|
; <H16> 5/28/92 BG Fixed a bug in GetHardwareInfoPatch. If you have the -Ext- bit
|
|
; set in your CPU ID register, -GetVIAInputs- gets called to read
|
|
; VIA1 to see what machine you really are. However, A1 was a bad
|
|
; register to save the A6 return value in. A3 is better.
|
|
; <SM7> 5/25/92 RB Changed a couple of branch longs to short branches since the
|
|
; code is not in patches anymore. Some VIA1 init code got lost in
|
|
; pass <SM5>, so it has been restored now.
|
|
; <SM6> 5/22/92 RB Removed an ENDIF
|
|
; <SM5> 5/22/92 RB Forgot to add comments in the previous checkin. Added tables for
|
|
; Cyclone, checks for MMC which identify a a Cyclone machine (for
|
|
; now I think) and got rid of the IF forCyclone changes previously
|
|
; made. Added VIA init stuff for Cyclone, its decoder table and
|
|
; video info.
|
|
; <SM4> 5/22/92 RB Making changes for Cyclone
|
|
; <SM3> 5/17/92 kc Roll the Horror changes. Comments follow: ¥ From
|
|
; UniversalPatch.a:
|
|
; <H14> 4/20/92 NJV Adding changes needed to support Patch ROMs
|
|
; <H13> 4/13/92 JC Remove dynamic speed determination from Sonora setup code.
|
|
; <H12> 2/20/92 JC Fix register trashing bug in test for Sonic code and remove
|
|
; temporary branch around Sonic test.
|
|
; <H11> 2/14/92 JC Clean up Sonora Memory controller initialization, dynamically
|
|
; determine clock speed, and add TestforSonic code.
|
|
; <T13> 4/26/91 ag Relocate the stack pointer after we jump into rom, otherwise a
|
|
; berr will cause ram to be written to!
|
|
; <T12> 4/22/91 ag added patch to reinitialize berr handler after jump into rom.
|
|
; removed aux wait state initialization in jaws.
|
|
; <T11> 2/16/91 BG Changed the Orwell initialization to understand 33MHz.
|
|
; <T10> 1/15/91 HJR Added new code in memoryCtrlInitPatch for Jaws initialization.
|
|
; <T7> 11/7/90 BG Made changes for new rev. of Orwell (2) permanent.
|
|
; <T4> 10/30/90 BG Added changes for new rev. of Orwell (2).
|
|
; <T3> 10/25/90 CCH Added support for ReAnimator when forRomulator equate is set.
|
|
; ¥ From Univeral.a:
|
|
; <H9> 12/16/91 HJR Export some symbols and introduce Decoder Niagra and Product
|
|
; Dartanian into product list. Temporarily use the same routine
|
|
; for CheckForJaws and CheckForNiagra until Niagra has some
|
|
; distinguishing characteristic.
|
|
; <H8> 12/12/91 SWC Don't touch RvMonP in InitVIAs if we're running on an MSC since
|
|
; that register offset is used for, among other things, RAM
|
|
; sizing.
|
|
; <T9> 12/7/90 BG (actually JMA) Added support for dual SCSI buses used on
|
|
; Eclipse. Also - merged CheckForRPU with new CheckForSCSI96
|
|
; routine into new patch.
|
|
; <T6> 1/18/90 SWC Fixed an alignment problem where code grew by 2 bytes in
|
|
; TestForIOP. Also changed FMCInit to FMCRPUInit since we don't
|
|
; know if we have parity yet.
|
|
; <T6> 10/29/90 CCH Fixed forRomulator conditional statement.
|
|
; <T5> 10/25/90 CCH Added support for ReAnimator when forRomulator equate is set.
|
|
; <SM2> 4/7/92 JSM Roll-in revision <63> from Reality:
|
|
; <63> 3/24/92 JSM Nuke more code names: boxAuroraCX25 is boxMacIIci, boxF19 is
|
|
; boxMacIIfx.
|
|
; <62> 1/27/92 KC Move Allign 16 macro above rombase table.
|
|
; <61> 1/23/92 RB Changed the order of items in the Decoder lookup table. Changed
|
|
; the Eclipse VIA info record.
|
|
; <60> 1/20/92 RB Backed out to the revision <58>. For some reason making the code
|
|
; that sets up a bus error handler a procedure would freeze the
|
|
; machine upon startup. Very weird because the problem is not
|
|
; obvious. If only that 040 emulator worked...added an ALIGN for
|
|
; the 040 emulator. Got rid of the padForOverpatch at the end of
|
|
; the file.
|
|
; <59> 1/15/92 RB Revisited terror changes. Added a forRomulator change. Made code
|
|
; that sets up the buss error handler a subroutine since it gets
|
|
; called twice.
|
|
; <58> 12/29/91 RB Added Terror changes and rolled in patches to support Quadras
|
|
; and PowerBooks.
|
|
; <57> 12/21/91 RB Need to change boxTim and boxEclipse to the release names.
|
|
; <56> 10/17/91 JSM Get rid of all the stupid conditionals.
|
|
; <55> 10/1/91 JSM DonÕt use onMvMac conditional, Modern Victorian never existed.
|
|
; <54> 10/1/91 JSM DonÕt use eclipseDebug.
|
|
; <53> 9/10/91 JSM Cleanup header.
|
|
; <52> 1/18/91 KIP <JDR> Add Sound8BitMono bit to the Universal ROM flags for TIM,
|
|
; since it has built-in sound input.
|
|
; <51> 10/24/90 JJ Rex V8: Roll in changes from Rex V8 splitoffs.
|
|
; <50> 10/22/90 JJ Rex V8: Change VISAChipBit to V8ChipBit.
|
|
; <49> 9/25/90 SAM Changed boxElsie/boxErickson to boxMacLC/boxMacIIsi
|
|
; <48> 9/13/90 MSH Converted Waimea to TIM. This involved the boxflag, names, and
|
|
; clock/PRAM implementation.
|
|
; <47> 9/1/90 BG Updated Eclipse-related information to reflect the EVT1 boards.
|
|
; <46> 8/15/90 BG Fixed an error in the conditionals at the bottom of JumpIntoROM.
|
|
; <45> 8/14/90 BG Added an address map definition for SONIC on Eclipse. This uses
|
|
; the previously unused Address23 in the I/O map tables.
|
|
; <44> 8/14/90 BG Saved the original bus error vector for the NUB on Eclipse.
|
|
; <43> 8/2/90 CCH Temporarily cleared hwCfgFPU on Eclipse.
|
|
; <42> 6/25/90 BG Modified the EclipseNuBus information to correctly reflect the
|
|
; fact that slot E is not available on the current prototypes.
|
|
; <41> 6/18/90 CCH Added eclipse-specific changes, and removed occurences of the
|
|
; onEclipse equate.
|
|
; <40> 6/11/90 GA Correct VideoInfo 24-bit base address for Erickson. Somehow, it
|
|
; seemed to get lost from <39>.
|
|
; <39> 6/7/90 HJR Changes the 24 Bit Address in MDU and Erickson to 32 Bit
|
|
; Addresses since the video stuff pulls that address and Quickdraw
|
|
; requires it to be a 32 bit address.
|
|
; <38> 5/25/90 MSH JAWS check was all wrong. Changed logical 24 Bit address in MDU
|
|
; and Erickson to reflect actual 24 Bit address.
|
|
; <37> 5/17/90 JJ Change address of diagnostic ROM for VISA decoder.
|
|
; <36> 5/14/90 MSH Moved built in video to logical slot E and the PDS connector to
|
|
; slot B.
|
|
; <35> 5/2/90 CV Updating nuBus slot info to reflect change in the video slot for
|
|
; Erickson.
|
|
; <34> 5/1/90 DAF Updating Erickson VideoInfo for Built-in Video in Slot $E.
|
|
; <33> 4/24/90 DAF Reordered Elsie VideoInfo records to match new RBVPrimaryInit.a
|
|
; <32> 4/21/90 GMR Reversed order of entries in RamInfo tables.
|
|
; <31> 4/20/90 JJ Removed support for VISA 1 from Elsie RAM Info Table.
|
|
; <30> 4/20/90 JJ Change initial sound volume value for Elsie and Erickson from 2
|
|
; to 6.
|
|
; <29> 4/12/90 MSH Fixed the Waimea clock/PRAM info in tables.
|
|
; <28> 4/11/90 JJ Change sound volume initilization value from 1 to 2 on Erickson
|
|
; and Elsie to avoid BURNIN rack problem.
|
|
; <27> 4/11/90 JJ Change VIA1Init table for Erickson and Elsie to set DDRA bits
|
|
; 0:2 to be outputs.
|
|
; <26> 4/4/90 JJ Modified Elsie Video Information Tables.
|
|
; <25> 4/4/90 MSH Added Waimea to the tables. Made the pad bytes at the bottom
|
|
; conditional for overpatching only.
|
|
; <24> 4/2/90 djw Fixup universal NuBusInfo tables for Elsie, Erickson, and
|
|
; Eclipse.
|
|
; <23> 3/26/90 CCH Added sound input to external feature flags for Erickson, Elsie,
|
|
; and Eclipse.
|
|
; <22> 3/23/90 JJ Made RAMInforElsie tables conditional on hasVISA2.
|
|
; <21> 3/22/90 JJ Fixed bug in JumpIntoROM. Now relocates pointers to Decoder
|
|
; Info and Product Info before "jmp @intoROM(d3.l)".
|
|
; <20> 3/9/90 JJ Changed RAMInfoElsie table to conform to VISA2 memory
|
|
; configurations.
|
|
; <19> 2/23/90 BG Moved reference to Orwell to before the Glue DecoderTable entry
|
|
; since Eclipse/Orwell will pass the GLUE test, but a MacII will
|
|
; fail the Orwell test.
|
|
; <18> 2/21/90 BG Fixed off-by-one error in Orwell setup code.
|
|
; <17> 2/20/90 CCH Set Eclipse smallest bank size to 4 meg.
|
|
; <16> 2/16/90 BG Modified TestForFPU to check if we're running on an 040 before
|
|
; the SFC check. Running on an 040 implies you have an FPU. The
|
|
; SFC check will fail on an 040 because it does not support
|
|
; coprocessor communications. Also modified OrwellDecoderTable to
|
|
; include the possibility of a DiagROM, etc.
|
|
; <15> 2/13/90 JJ Stupid mistake in Version <14>.
|
|
; <14> 2/13/90 JJ Added VISA chip indicator to External Feature flags in VISA
|
|
; decoder table and Elsie information table.
|
|
; <13> 2/9/90 BG Adding Eclipse-specific hardware information. Also added a
|
|
; *CheckForOrwell* routine to determine if we're dealing with
|
|
; Orwell decoder. Also added Orwell initialization code in
|
|
; JumpIntoROM.
|
|
; <12> 2/7/90 OR Add CheckForVISADecoder routine and all information tables for
|
|
; Elsie.
|
|
; <11> 2/7/90 CV Rearranged order of CheckFeatures & CheckOptionals to use d1,
|
|
; not d3 in TestForFPU. d3 contains warmstart value. Sorry!
|
|
; <10> 2/4/90 GMR Fixed VIA init table for Erickson, so it properly initializes
|
|
; the vACR reg for Egret.
|
|
; <9> 2/4/90 CV Removed isUniversal conditional on TestForFPU. Caused HcMac &
|
|
; Macpp to fail.
|
|
; <8> 2/3/90 CV Added TestForFPU to check for an optional FPU.
|
|
; <7> 2/1/90 CV Adding a table for via1 initialization for Erickson. Erickson
|
|
; was using the IIci table, but EGRET requires different
|
|
; initialization. On Erickson, three lines are used to communicate
|
|
; with EGRET and five lines are unconnected.
|
|
; <6> 1/25/90 GMR Renamed the ADB/Clock types so they don't conflict with assembly
|
|
; conditionals (like iopADB).
|
|
; <5> 1/15/90 GMR Added ADB and Clock/Pram bits to External Features longword, to
|
|
; help support Erickson/Elsie which use the Egret chip.
|
|
; <4> 1/11/90 CCH Added include of ÒHardwarePrivateEqu.aÓ.
|
|
; <3> 1/8/90 CV Adding table information to allow recognition of Erickson as a
|
|
; new CPU. Changing the via1 id value for AuroraSE25 to 0. The
|
|
; value it was set to ($16) conflicts with Erickson's cpu id.
|
|
; <2> 1/2/90 SWC Changed CheckForOSSFMC to work with TI as well as NCR parts.
|
|
; <2.5> 11/15/89 GMR Added TestForRPU to check for the optional RPU chip on OSS/FMC,
|
|
; changed the decoder table for OSS/FMC and the InfoF19 table.
|
|
; Fixed bug in TestForIOP when setting increment mode.
|
|
; <2.4> 8/22/89 BBM UGLY HACK. made a quick patch to the bbu table just to get emacs
|
|
; working.
|
|
; <2.3> 7/25/89 CCH Changed JumpIntoROM to preserve the value in the VBR if
|
|
; forRomulator is true.
|
|
; <2.2> 7/16/89 GGD Changed the product info for the former Aurora 16 to be the same
|
|
; as Aurora 25, but without the PGC option. Added a flag to the
|
|
; ExtValid flags of Aurora 25 to indicate that it has the PGC
|
|
; option installed. Renamed AuroraCX25 to be MacIIciPGC and
|
|
; AuroraCX16 to be MacIIci.
|
|
; <2.0> 6/30/89 GGD Initialized the new DefaultRSRCs field in the ProductInfo
|
|
; record. Added some padding to allow for overpatching. Added
|
|
; NuBus Slot Info.
|
|
; <¥2.1> 6/30/89 GGD Changed resource combos from 0,1 to 1,2
|
|
; <2.1> 6/30/89 GGD Changed the DefaultRSRCs from {0,1} to {1,2}
|
|
; <2.0> 6/30/89 GGD Initialized the new DefaultRSRCs field in the ProductInfo record.
|
|
; Added some padding to allow for overpatching. Added NuBus Slot Info.
|
|
; <1.9> 6/12/89 djw Added slot video pram addr to video table
|
|
; <1.8> 6/11/89 GGD Added Video, Ram Bank, hwCfgFlags, and ROM85 info to tables.
|
|
; Updated GetHwInfo to also return the hwCfgFlags. Updated VIA2
|
|
; initialization values.
|
|
; <1.7> 6/10/89 GGD Added info for new aurora boxes. GetHwInfo now clears the beok
|
|
; bit when done.
|
|
; <1.6> 5/29/89 GGD Fixed wrong register bug in FMC initialization. Removed the Test
|
|
; in Ram checks.
|
|
; <1.5> 5/20/89 GGD Updated to use new IOP equates from HardwareEqu, deleted local
|
|
; IOP equates.
|
|
; <1.4> 5/16/89 rwh separated out Mac II Via 2 info to set MMU control bit as an
|
|
; output.
|
|
; <1.3> 5/15/89 GGD Changed RBV BufB initialization to disable Par.Test~ so that
|
|
; correct parity will be generated.
|
|
; <1.2> 5/10/89 CCH Added a test that will make the vFC3 bit an output when running
|
|
; in RAM.
|
|
; <1.1> 5/1/89 GGD Fixed conditionals in CheckForGLUE so that NuMac will work
|
|
; again.
|
|
; <1.0> 4/30/89 GGD Adding to EASE for the first time. Support for Universal ROM.
|
|
;__________________________________________________________________________________________________
|
|
|
|
print off
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'HardwarePrivateEqu.a'
|
|
INCLUDE 'UniversalEqu.a'
|
|
INCLUDE 'PowerPrivEqu.a'
|
|
INCLUDE 'STEqu.a'
|
|
INCLUDE 'Slots.a'
|
|
INCLUDE 'DepVideoEqu.a' ; <58> rb
|
|
INCLUDE 'EgretEqu.a' ; <SM38>
|
|
print on
|
|
print nomdir
|
|
machine mc68030
|
|
mc68881 ; needed for TestForFPU <SM28>
|
|
|
|
|
|
Universal proc export
|
|
import CPUIDProductLookup,ProductLookup,DecoderLookup
|
|
import BaseOfRom, CudaInit
|
|
import SendEgretCmd ; <SM38>
|
|
EXPORT CheckForUnknown
|
|
export GetHardwareInfo
|
|
export GetExtHardwareInfo ; <SM17>
|
|
export JumpIntoROM
|
|
export InitVIAs
|
|
EXPORT CheckNextMap,MapFound ;<SM31> ; <H2>
|
|
IF hasCPUIDRegister THEN ; ; <SM24> rb <SM36> rb
|
|
EXPORT GetCPUIDReg ;<SM49>
|
|
ENDIF
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: JumpIntoROM
|
|
; Inputs: A6 - return address
|
|
;
|
|
; Outputs: A0 - Pointer to DecoderInfo record for this machine
|
|
; A1 - Pointer to ProductInfo record for this machine
|
|
; D0 - Flags indicating which base addresses are valid
|
|
; D1 - Flags indicating which external features are valid
|
|
; D2 - Bits 31..16, hwCfgFlags info (possibly unknown)
|
|
; D2 - Bits 15..8, BoxFlag info (possibly unknown)
|
|
; D2 - Bits 7..0, Address Decoder Kind (zero if unknown)
|
|
;
|
|
; Destroys: A2,A3,SP,D3,D4,D5
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Locates the System ROM, which we are executing out of,
|
|
; but which may be mapped down to zero (overlay mode).
|
|
; We will jump into the ROM at its normal base address,
|
|
; and then initialize the VIAs to disable overlay.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
with DecoderInfo,ProductInfo,DecoderKinds
|
|
JumpIntoROM
|
|
move.l #aStack,sp ; set stack pointer value
|
|
movea.l a6,a4 ; save the return address
|
|
|
|
; Setup VBR to point to a temporary Bus Error handler, because we need to use
|
|
; Bus Errors to destinguish the address decoders on the 68020/030 machines.
|
|
|
|
lea GotBusError,a0 ; get the handler address
|
|
move.l a0,d0 ; value to search for
|
|
@loop cmp.l -(a0),d0 ; check for a match
|
|
beq.s @found ; use the entry if it matches
|
|
tst.l (a0) ; check for end of list
|
|
bne.s @loop ; if not, keep searching
|
|
lea BusErrVct,a0 ; set it up in RAM
|
|
move.l d0,(a0) ; assume ram based, insert entry
|
|
@found subq.w #BusErrVct,a0 ; make it the bus error vector
|
|
|
|
IF forRomulator THEN ; <T5>
|
|
TestInRAM a3 ; are we in RAM?
|
|
beq.s @notInRAM ;
|
|
movec vbr,d5 ; save contents of vbr <T5>
|
|
movec vbr,a3 ; get vbr address in a1
|
|
move.l BusErrVct(a3),d2 ; save original (read: NUB) buserr vect
|
|
movec d2,USP ; ... in an out-of-the-way place
|
|
move.l BusErrVct(a0),BusErrVct(a3) ; copy old vector to new table
|
|
@notInRAM
|
|
ELSE ; <T6>
|
|
movec.l a0,vbr ; install the vector table
|
|
ENDIF
|
|
|
|
@TryAgain moveq.l #0,d2 ; figure it out from scratch
|
|
bsr6 GetHardwareInfo ; figure out what we are running on
|
|
btst.l #ROMExists,d0 ; see if we have a ROM
|
|
beq.s norom ; if not, we're screwed
|
|
|
|
; Now figure out what the new base of ROM should be,
|
|
|
|
IF forRomulator THEN ; <T5>
|
|
TestInRam A2 ; running in RAM? <T5>
|
|
bne.s intoROM ; yep, skip this.. <T5>
|
|
endif
|
|
biglea BaseOfRom,a2 ; where we currently start
|
|
|
|
move.l ROMAddr(a0),d3 ; where we want to start (from savepatch) <3> <cv>
|
|
sub.l a2,d3 ; offset we need to add to relocate <3> <cv>
|
|
adda.l d3,a0 ; relocate decoder info pointer <3> <cv>
|
|
adda.l d3,a1 ; relocate product info pointer <3> <cv>
|
|
|
|
; if not forRamRom then ; ¥¥¥ need to make this a runtime check ¥¥¥
|
|
adda.l d3,a4 ; relocate the return address
|
|
jmp intoROM(d3.l) ; relocate our program counter
|
|
; endif
|
|
intoROM ; now we are in ROM
|
|
|
|
; Setup VBR to point to a temporary Bus Error handler, because we need to use
|
|
; Bus Errors to destinguish the address decoders on the 68020/030 machines.
|
|
|
|
adda.l d3,sp ; relocate the stack to rom addresses <T13>
|
|
|
|
norom
|
|
lea GotBusError,a0 ; get the handler address <T12>
|
|
move.l a0,d0 ; value to search for <T12>
|
|
@loop cmp.l -(a0),d0 ; check for a match <T12>
|
|
beq.s @found ; use the entry if it matches <T12>
|
|
tst.l (a0) ; check for end of list <T12>
|
|
bne.s @loop ; if not, keep searching <T12>
|
|
lea BusErrVct,a0 ; set it up in RAM <T12>
|
|
move.l d0,(a0) ; assume ram based, insert entry <T12>
|
|
@found subq.w #BusErrVct,a0 ; make it the bus error vector <T12>
|
|
|
|
IF forRomulator THEN ; <T12>
|
|
TestInRAM a3 ; are we in RAM? <T12>
|
|
beq.s @notInRAM ; <T12>
|
|
movec vbr,d5 ; save contents of vbr <T12>
|
|
movec vbr,a3 ; get vbr address in a1 <T12>
|
|
move.l BusErrVct(a3),d2 ; save original (read: NUB) buserr vect <T12>
|
|
movec d2,USP ; ... in an out-of-the-way place <T12>
|
|
move.l BusErrVct(a0),BusErrVct(a3) ; copy old vector to new table <T12>
|
|
@notInRAM
|
|
ELSE ; <T12>
|
|
movec.l a0,vbr ; install the vector table <T12>
|
|
ENDIF
|
|
|
|
@TryAgain moveq.l #0,d2 ; figure it out from scratch <T12>
|
|
bsr6 GetHardwareInfo ; figure out what we are running on <T12>
|
|
|
|
IF NOT ROMinRAM THEN ; <SM22> rb
|
|
bsr6 InitVIAs ; initialize the VIAs (turns off vOverlay) <T12>
|
|
ENDIF ; <SM22> rb
|
|
|
|
; Here, after running GetHardwareInfo we have: <SM10>{rbm}<2>
|
|
; <SM10>{rbm}<2>
|
|
; a0 - Pointer to table of base addresses <SM10>{rbm}<2>
|
|
; a1 - Pointer to ProductInfo record for this machine <SM10>{rbm}<2>
|
|
; d0 - Flags indicating which base addresses are valid <SM10>{rbm}<2>
|
|
; d1 - Flags indicating which external features are valid <SM10>{rbm}<2>
|
|
; d2 - Bits 31..16, hwCfgFlags info (possibly unknown) <SM10>{rbm}<2>
|
|
; d2 - Bits 15..8, BoxFlag info (possibly unknown) <SM10>{rbm}<2>
|
|
; d2 - Bits 7..0, Address Decoder Kind (zero if unknown) <SM10>{rbm}<2>
|
|
; <SM10>{rbm}<2>
|
|
; CudaInit implies a SyncAck cycle which synchronizes Cuda to the system and disables <SM10>{rbm}<2>
|
|
; all asynchronous messages sources (Auto Poll, RTC, Power Messages, Unknown). No further <SM10>{rbm}<2>
|
|
; individual disabling of asynchronous message sources is required. (R. Montagne 5/25/92) <SM10>{rbm}<2>
|
|
; <SM10>{rbm}<2>
|
|
move.l d0,d3 ; save a copy of d0 <SM11>
|
|
move.l #EgretFWMask,d0 ; mask for Egret Firmware <SM10>{rbm}<2>
|
|
and.l d1,d0 ; isolate the field <SM10>{rbm}<2>
|
|
beq.s @CudaDone
|
|
|
|
cmpi.l #$3000000, D0
|
|
bne.s @CudaDone ; if not, just exit <SM10>{rbm}<2>
|
|
|
|
IF NOT ROMinRAM THEN ; <SM22> rb
|
|
BigBSR6 CudaInit ;Setup Cuda Sysnc Ack with System <SM10>{rbm}<2>
|
|
ENDIF ; <SM22> rb
|
|
@CudaDone
|
|
move.l d3,d0 ; restore d0 <SM11>
|
|
|
|
|
|
IF forSTP601 THEN
|
|
jmp (a4) ; Orwell,djmec already inited...return
|
|
ENDIF
|
|
|
|
IF hasOSS THEN ; <SM36> rb
|
|
btst.l #OSSExists,d0 ; see if we have an OSS
|
|
beq.s @noOSS ; if not, don't need to init it
|
|
movea.l OSSAddr(a0),a3 ; get the OSS base address
|
|
move.b #OSSRomInit,OSSRomCntl(a3) ;overlay off, 2 ROM wait states
|
|
@noOSS
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasFMC THEN ; <SM36> rb
|
|
btst.l #FMCExists,d0 ; see if we have a FMC
|
|
beq.s @noFMC ; if not, don't need to init it
|
|
movea.l FMCAddr(a0),a3 ; get the FMC base address
|
|
move.w #FMCRPUInit,d3 ; initial value for config register <T6>
|
|
moveq.l #16-1,d4 ; loop counter to load 16 bits
|
|
@FMCload move.b d3,FMCConfig(a3) ; load in a bit <1.6>
|
|
lsr.w #1,d3 ; put next bit into position
|
|
dbra d4,@FMCload ; repeat till all bits loaded
|
|
move.b d3,FMCLatch(a3) ; latch the config data
|
|
@noFMC
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasSonora THEN ; begin hasSonora <H11>.Start <SM36> rb
|
|
move.l ExtValid(a1),d3 ; get External Flags
|
|
btst.l #SonoraExistsBit,d3 ; see if we have an Sonora ASIC
|
|
beq @noSonora ; IF we have a Sonora THEN
|
|
|
|
lea CPUIDReg,A2 ;get value in CPU ID Reg <H13>.Start
|
|
move.l (a2),d3
|
|
and.l #$0000ff00,d3 ; only look at CPU ID reg Design Center Value
|
|
|
|
movea.l RBVAddr(a0),a2 ; get base of RBV/VIA2 Registers
|
|
move.b #0,SonoraVRAMSize(a2) ;force VRAM to 256k for now
|
|
move.b #$40,SonoraRAMSize(a2) ;force to 25 Mhz PDS slot speed <SM4> rb
|
|
move.b #3,SonoraSpeedReg(a2) ;Set up for 33Mhz timing
|
|
cmpi.w #cpuIDHiEnd,d3 ; check if we are a high end box
|
|
bge.s @noSonora ; branch if high end box
|
|
lea CPUIDReg,A2 ;get value in CPU ID Reg <H27><SM31>
|
|
move.l (a2),d3 ; <H27><SM31>
|
|
and.w #cpuIDFieldMask,d3 ; d3 = ID field of CPU ID Register <H26><SM31>
|
|
cmpi.w #Vail33IDField,d3 ; is it a 33 MHz Vail ?? <H26><SM31>
|
|
beq.s @noSonora ; yep, don't change the timing <H26><SM31>
|
|
movea.l RBVAddr(a0),a2 ; get base of RBV/VIA2 Registers <H29><SM31>
|
|
move.b #2,SonoraSpeedReg(a2) ;Set up for 25Mhz or less timing <H13>.End
|
|
@noSonora ; end hasSonora <H11>.End
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasOrwell THEN ; <SM36> rb
|
|
; Eclipse/040 Memory Controller INIT
|
|
cmp.b #OrwellDecoder,DecoderKind(a1) ; see if we have an Orwell Mem. Cntrlr
|
|
bne.s @noOrwell ; NOPE ... we don't need to init. it
|
|
cmp.b #boxRiscQuadra700,ProductKind(a1) ; see if we're on a RISC Quadra <SM54>
|
|
beq.s @noOrwell ; don't reset orwell then <SM54>
|
|
cmp.b #boxRiscQuadra900,ProductKind(a1) ; see if we're on a RISC Quadra <SM54>
|
|
beq.s @noOrwell ; don't reset orwell then <SM54>
|
|
cmp.b #boxRiscQuadra950,ProductKind(a1) ; see if we're on a RISC Quadra <SM54>
|
|
beq.s @noOrwell ; don't reset orwell then
|
|
|
|
; Set up various Orwell configuration registers to useable values.
|
|
|
|
movea.l DecoderAddr(a0),a3 ; get base address of Orwell regs <SM17>
|
|
move.l #ORWELL_INIT25,d4 ; get Orwell 25MHz initialization value <T11>
|
|
moveq.l #OrCfgRegSize-3,d3 ; (34-3 = 34-1-2) -1 for DBRA, <T4><T7>
|
|
; -2 because 32-bit max constant size <T4>
|
|
movea.l VIA2Addr(a0),a2 ; get base of VIA2 to check for 33 MHz <T11>
|
|
bclr #v2Speed,VDirB(a2) ; make sure the 25/33MHz direction=input<T11>
|
|
btst #v2Speed,VBufB(a2) ; are we running at 25 MHz or 33 MHz? <T11>
|
|
beq.s @25MHz ; IF CPU_Speed == 33MHz THEN <T11>
|
|
move.l #ORWELL_INIT33,d4 ; get Orwell 33MHz init. value <T11>
|
|
@25MHz ; ENDIF <T11>
|
|
; Note - the above configuration constants are ONLY accurate for non-parity <T11>
|
|
; operation. <T11>
|
|
|
|
lea OrBankBCfgAddr(a3),a2; get address of config regs. <T11>
|
|
|
|
@OrwellINIT move.l d4,(a2)+ ; send that bit out there
|
|
lsr.l #1,d4 ; get the next bit in position
|
|
dbra d3,@OrwellINIT ; repeat til all bits loaded
|
|
|
|
; now move in the last two bits that didnt fit in the original 32-bit constant<T4><T7>
|
|
|
|
moveq #ORINITWaitWr1,d4 ; get initial value of optional write wait state<T4><T7>
|
|
move.l d4,(a2)+ ; ... and send that bit out <T4><T7>
|
|
|
|
; RAS precharge (the last bit) is done separately below because it too relies <T11>
|
|
; on the clock speed the processor is running at. <T11>
|
|
|
|
; Now hit the associated latch registers to actually store the values
|
|
|
|
move.l d3,OrLoadBanks(a3) ; initialize DRAM bank starting addrs
|
|
move.l d3,OrLoadSpeeds(a3) ; initialize Clock/DRAM/ROM speeds
|
|
move.l d3,OrLoadRefresh(a3); initialize refresh rate
|
|
move.l d3,OrLoadParity(a3) ; initialize parity on/off + type
|
|
move.l d3,OrLoadMode(a3) ; initialize page mode (on/off) <T4><T7>
|
|
move.l d3,OrLoadWaitStates(a3); initialize optional wait states <T4><T7>
|
|
|
|
; RAS Precharge timing is different depending on 25/33 MHz.
|
|
|
|
|
|
move.l OrClkSpeedAddr(a3),d4; now that clock speed is set, get it <T11>
|
|
btst #0,d4 ; only LSBit is valid from each reg addr<T11>
|
|
beq.s @use33MHzvalue ; IF Clock_Speed == 25MHz THEN <T11>
|
|
moveq #ORINITRAS25,d4 ; get value of 25 MHz RAS precharge <T4><T7><T11>
|
|
bra.s @initRAS ; and get on with it <T11>
|
|
@use33MHzvalue ; ELSE <T11>
|
|
moveq #ORINITRAS33,d4 ; get value of 33 MHz RAS precharge <T4><T7><T11>
|
|
@initRAS ; ENDIF
|
|
move.l d4,(a2) ; ... and finish init of config reg <T4><T7>
|
|
move.l d3,OrLoadPrecharge(a3); initialize RAS precharge (on/off) <T4><T7>
|
|
@noOrwell
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasJaws THEN ; <SM36> rb
|
|
btst.l #JAWSExists,d0 ; see if we have a JAWS <T10> HJR
|
|
beq.s @noJAWS ; if not, don't need to init it
|
|
movea.l JAWSAddr(a0),a2 ; get base address of Jaws regs
|
|
movea.l a2,a3 ; copy the register
|
|
adda.l #JAWSGetCPUClock,a3 ; get address of CPU clock register
|
|
move.b (a3),d3 ; read CPU clock register
|
|
andi.b #1,d3 ; clear the top bits
|
|
move.b d3,JAWSRAMWaitS(a2) ; set ram wait states according to the speed register
|
|
@noJAWS
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasYMCA THEN ; <SM36> rb
|
|
cmp.b #YMCADecoder,DecoderKind(a1) ; Do we have a YMCA <SM26> fau start
|
|
bne @noYMCA ; Not a YMCA <SM26> fau end
|
|
|
|
Move.l DecoderAddr(a0),A2 ; Get Base of YMCA. <SM23> <SM26> <SM34>
|
|
Cmp.b #BoxQuadra840AV,ProductKind(a1) ; Are we running on a Cyclone40 <SM34> <LW2><SM55>
|
|
Beq.s @DoCyclone40 ; if so, go program it <SM34>
|
|
Cmp.b #BoxCyclone33,ProductKind(a1) ; Are we running on a Cyclone33 <SM34>
|
|
Beq.s @DoCyclone33 ; if so, go program it <SM34>
|
|
Cmp.b #BoxTempest33,ProductKind(a1) ; Are we running on a Tempest25 <SM34> <LW2>
|
|
Beq.s @DoTempest33 ; if so, go program it <SM34>
|
|
Cmp.b #BoxCentris660AV,ProductKind(a1) ; Are we running on a Tempest25 <SM34> <LW2><SM55>
|
|
Beq @DoTempest25 ; if so, go program it <SM34>
|
|
Bra @noYMCA ; Not a Cyclone Type Machine
|
|
|
|
@DoCyclone40
|
|
|
|
Move.l #0,YMCA_DRAMspeed0(A2) ; Set DRAM speed to 60ns with a 40MHz CPU <SM34><LW7>
|
|
Move.l #-1,YMCA_DRAMspeed1(A2) ; <SM34><LW7
|
|
Move.l #0,YMCA_CPUspeed0(A2) ; Set CPU Speed to 40 MHz <SM34><LW7
|
|
Move.l #-1,YMCA_CPUspeed1(A2)
|
|
Move.l #0,YMCA_ROMspeed0(A2) ; Set ROM speed to 127ns (7 cycles). <SM34><LW7>
|
|
Move.l #0,YMCA_ROMspeed1(A2) ; <SM34><LW7>
|
|
Move.l #-1,YMCA_ROMspeed2(A2) ; <SM34>
|
|
|
|
; Program MUNI if it exists
|
|
|
|
bsr6 GetExtHardwareInfo ; Get the bits for extended features 32-63 <SM34>
|
|
beq @NoYMCA ; No MUNI here <SM34>
|
|
Move.l #$1c,MUNIBase+MUNI_Control ; Set MUNI for 33MHz. <SM34>
|
|
|
|
Bra.s @noYMCA ; Skip over Tempest programming <SM34>
|
|
|
|
@DoCyclone33
|
|
@DoTempest33 ; <SM34>
|
|
|
|
Move.l #-1,YMCA_DRAMspeed0(A2) ; Set DRAM speed to 60ns with a 33MHz CPU <SM23>
|
|
Move.l #0,YMCA_DRAMspeed1(A2) ; <SM23>
|
|
Move.l #-1,YMCA_CPUspeed0(A2) ; Set CPU Speed to 33 MHz <SM23>
|
|
Move.l #0,YMCA_CPUspeed1(A2)
|
|
Move.l #-1,YMCA_ROMspeed0(A2) ; Set ROM speed to 125 (6 cycles). <SM23> <LW7>
|
|
Move.l #-1,YMCA_ROMspeed1(A2) ; <SM23> <LW7>
|
|
Move.l #0,YMCA_ROMspeed2(A2) ; <SM23> <LW7>
|
|
|
|
; Program MUNI if it exists
|
|
|
|
bsr6 GetExtHardwareInfo ; Get the bits for extended features 32-63 <SM32>
|
|
beq.s @NoYMCA ; No MUNI here <SM32>
|
|
Move.l #$18,MUNIBase+MUNI_Control ; Set MUNI for 33MHz. <SM23>
|
|
|
|
Bra.s @NoYMCA ; Skip over Tempest programming <SM26>
|
|
|
|
@DoTempest25
|
|
Move.l #0,YMCA_DRAMspeed0(A2) ; Set DRAM speed to 60ns with a 25MHz CPU <SM26><LW7>
|
|
Move.l #0,YMCA_DRAMspeed1(A2) ; <SM26><LW7>
|
|
Move.l #0,YMCA_CPUspeed0(A2) ; Set CPU Speed to 25 MHz <SM26><LW7>
|
|
Move.l #0,YMCA_CPUspeed1(A2)
|
|
Move.l #0,YMCA_ROMspeed0(A2) ; Set ROM speed to 140ns (5 cycles). <SM26><LW7
|
|
Move.l #-1,YMCA_ROMspeed1(A2) ; <SM26>
|
|
Move.l #0,YMCA_ROMspeed2(A2) ; <SM26>
|
|
|
|
; Program MUNI if it exists
|
|
|
|
bsr6 GetExtHardwareInfo ; Get the bits for extended features 32-63 <SM32>
|
|
btst.l #MUNIExists-32,d0 ; Normalize MUNIExists since it's in 32-63 <SM32>
|
|
beq.s @NoYMCA ; No MUNI here <SM32>
|
|
Move.l #$14,MUNIBase+MUNI_Control ; Set MUNI for 25MHz. <SM32>
|
|
|
|
@NoYMCA
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasVisaDecoder THEN ; <SM36> rb
|
|
cmp.b #VISADecoder,DecoderKind(a1) ; do we have a VISA <SM27>
|
|
bne.s @noVISA ; if not don't do anything <SM27>
|
|
; <SM27>
|
|
; VISA machines need there screens greyed out earlier than primary init time <SM27>
|
|
; to avoid garbage being left over on the screen from a previous reboot <SM27>
|
|
|
|
move.l VDACAddr(a0),a2 ; get base address of Color Table chip <SM27>
|
|
move.l a2,a3 ; save base address in a3 <SM27>
|
|
clr.b V8DACwCntlReg(a2) ; clears the overlay enable bit and puts ariel in slave mode <SM27>
|
|
; ; to insure all outputs are off while CLUT is being filled <SM27>
|
|
adda #V8DACwDataReg,a2 ; point to data register <SM27>
|
|
clr.b V8DACwAddReg-V8DACwDataReg(a2) ; start at the beginning of CLUT, 4-bit mode <SM27>
|
|
|
|
move.b #$7F,d3 ; get a 50% value <SM27>
|
|
move #$FF,d4 ; get count <SM27>
|
|
@Repeat move.b d3,(a2) ; put red (CLUT autoincrements destination address) <SM27>
|
|
move.b d3,(a2) ; put green <SM27>
|
|
move.b d3,(a2) ; put blue <SM27>
|
|
dbra d4,@Repeat ; <SM27>
|
|
|
|
ori.b #$08,V8DACwCntlReg(a3) ; turn video on by putting machine in master mode <SM27>
|
|
|
|
@noVISA
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasDJMEMC THEN ; <SM36> rb
|
|
; djMEMC Configuration Register initialization <H18> thru next <H18>
|
|
; (Done here so that it isn't done multiple times in SizeMemPatch) <SM30> begin
|
|
|
|
move.l ExtValid(a1),d3 ; get External Flags
|
|
btst.l #djMEMCChipBit,d3 ; see if we have a djMEMC
|
|
beq @nodjMEMC ; IF we have a djMEM THEN
|
|
cmp.b #boxRiscCentris650,ProductKind(a1) ; see if we're on a RISC Wombat Centris650 <SM54>
|
|
beq @nodjMEMC ; don't reset djMEMC then <SM54>
|
|
cmp.b #boxRiscQuadra800,ProductKind(a1) ; see if we're on a RISC Wombat Quadra800 <SM54>
|
|
beq @nodjMEMC ; don't reset djMEMC then <SM54>
|
|
cmp.b #boxRiscCentris610,ProductKind(a1) ; see if we're on a RISC Wombat Centris610 <SM54>
|
|
beq @nodjMEMC ; don't reset djMEMC then <SM54>
|
|
|
|
; Set up djMEMC+BIOS Configuration Registers:
|
|
; -------------------------------------------
|
|
;
|
|
; Get machine type + CPU speed information from VIA1
|
|
;
|
|
; Useful VIA1 PortA bits to read: PA6, PA4, PA2, PA1 ($56)
|
|
;
|
|
; PA6 = Lego (1), or Frigidaire (0) plastics for Wombat
|
|
; PA4, PA2 = CPU Speed. 0=20MHz, 1=25MHz, 2=33MHz, 3=40MHz
|
|
; PA1 = WLCD (0) or NOT! [Reserved] (1)
|
|
;
|
|
; Retrieve CPU Speed information from VIA1 Port A
|
|
|
|
move.l VIA1Addr(a0),a2 ; get VIA1 address to get machine/cpu_speed info
|
|
moveq #%00101000,d3 ; force VIA1 VDirA to have the correct directions
|
|
eieioSTP
|
|
move.b d3,VDirA(a2) ; ... so we can read the CPU ID extension info
|
|
moveq #%00010100,d3 ; get VBufA, bits PA4, PA2 (dont need PA6, PA1)
|
|
eieioSTP
|
|
and.b VBufA(a2),d3 ; get plastics_type/cpu_speed information
|
|
@hasValue lsr.b #2,d3 ; shift over to get PA2 in LSBit
|
|
btst #4-2,d3 ; test PA4. remember it's been shifted from bit pos. 4->2
|
|
beq.s @PA4IsZero ; if its already zero, don't do anything
|
|
bset #1,d3 ; otherwise move it down to correct place for indexing
|
|
@PA4IsZero andi.b #$03,d3 ; make sure ONLY bottom 2 bits are set
|
|
|
|
moveq.l #-1,d4 ; initial offset into @MachineTbl-one_entry <H35> thru next <H35> <SM57>
|
|
@nextEntry addq.l #1,d4 ; get next entry
|
|
tst.w (@MachineTbl,d4.w*2) ; if entry is zero, you've hit EndOfTable
|
|
beq.s @unknownMachine ; deal with unknown machine
|
|
moveq.l #%01010110,d0 ; CPU ID mask value for VIA
|
|
eieioSTP
|
|
and.b VBufA(a2),d0 ; get CPU ID value
|
|
cmp.b (@MachineTbl+1,d4.w*2),d0 ; is it this machine?
|
|
bne.s @nextEntry ; no, try again
|
|
LEA @djConfigTable,A3 ; assume original table
|
|
move.b (@MachineTbl,d4.w*2),d0 ; check whether we're an Original or a Bumped machine
|
|
beq.s @doIt ; 0=Original, use @djConfigTable.
|
|
@unknownMachine ; SpeedBump or Unknown machine, assume SpeedBump
|
|
LEA @BumpConfigTable,A3 ; use SpeedBump configuration table
|
|
@doIt
|
|
LEA MEMCAddr,A2 ; Get djMEMC base
|
|
move.w (a3,d3.w*2),d0 ; use CPU speed as index into table for config value <H35> <SM57>
|
|
MOVE.L D0,MEMCconfig(A2) ; set up configuration register
|
|
move.w (@djRefreshTable,d3.w*2),d0 ; also use CPU speed as index into refresh period table
|
|
MOVE.L D0,MEMCRefresh(A2) ; set up refresh period
|
|
LEA BIOSAddr,A2 ; get base of BIOS
|
|
MOVE.L BIOS_Config(A2),d0 ; get Config register value
|
|
andi.b #$F7,d0 ; drop old D0{0:0} value
|
|
or.b (@BIOS_Config,d3.w),d0 ; only change bit 0 of this register
|
|
MOVE.L d0,BIOS_Config(A2) ; and write it out (only bottom 8-bits "stick")
|
|
move.w (@BIOS_Timeout,d3.w*2),d0 ; get watchdog timer timeout count-down value
|
|
MOVE.L d0,BIOS_Timeout(A2) ; and and write this out
|
|
bra.s @nodjMEMC ; finished with memory controller initialization
|
|
|
|
; djMEMC Configuration register initialization values for different CPU speeds
|
|
;
|
|
; [ See the djMEMC ERS for a full description of the Configuration Register ]
|
|
|
|
align 4 ; longword align
|
|
|
|
; djMEMC Configuration Register initialization values
|
|
|
|
@djConfigTable
|
|
@dj20Config dc.w %0000000100000001 ; fastwr=1, ROMspeed=1
|
|
@dj25Config dc.w %0000000000011010 ; drpchg=1, drpw=1, ROMspeed=2
|
|
@dj33Config dc.w %0000000010100011 ; mhz33=1, cyc23ta=1, ROMspeed=3 <H24>
|
|
@dj40Config dc.w %0000001011110100 ; dwcpw=1, mhz33=1, drcpw=1, cyc2ta=1, drpchg=1, ROMspeed=4 <H22>
|
|
|
|
; DRAM refresh cycle times assuming a 15.6µs refresh period <H25>
|
|
; (Refresh = (MHz * 15.6 ) - 27). Fractional parts are rounded DOWN <H25>
|
|
|
|
@djRefreshTable
|
|
@dj20Refresh dc.w 285 ; (20MHz * 15.6µs) - 27 <H25>
|
|
@dj25Refresh dc.w 363 ; (25MHz * 15.6µs) - 27 <H25>
|
|
@dj33Refresh dc.w 487 ; (33MHz * 15.6µs) - 27 <H25>
|
|
@dj40Refresh dc.w 597 ; (40MHz * 15.6µs) - 27 <H25>
|
|
|
|
; BIOS Configuration Register initialization values <h28>
|
|
|
|
@BIOS_Config
|
|
@BIOS_Config20 dc.b %00000001 ; BCLK_25 = 1 <H28>
|
|
@BIOS_Config25 dc.b %00000001 ; BCLK_25 = 1 <H28>
|
|
@BIOS_Config33 dc.b 0 ; BCLK_25 = 0 <H28>
|
|
@BIOS_Config40 dc.b 0 ; BCLK_25 = 0 <H28>
|
|
|
|
; BIOS watchdog timer timeout count-down value <H28>
|
|
|
|
@BIOS_Timeout
|
|
@BIOS_Timeout20 dc.w $0280 ; <H28>
|
|
@BIOS_Timeout25 dc.w $01E0 ; <H28>
|
|
@BIOS_Timeout33 dc.w $00D5 ; <H28>
|
|
@BIOS_Timeout40 dc.w 0 ; <H28>
|
|
|
|
; Table for determining whether or not to use "SpeedBump"ed Config values <H35> thru next <H35> <SM57>
|
|
|
|
@DJ_ORIG EQU 0
|
|
@DJ_BUMP EQU 1
|
|
@MachineTbl ; Type CPU VIA ID
|
|
dc.b @DJ_ORIG,%00010010 ; 33MHz Frigidaire package (Quadra 800) <SM60>
|
|
dc.b @DJ_BUMP,%00010110 ; 40MHz Frigidaire package (unreleased) <SM60>
|
|
dc.b @DJ_ORIG,%01000000 ; 20MHz WLCD (Centris 610)
|
|
dc.b @DJ_BUMP,%01000100 ; 25MHz WLCD (Quadra 610)
|
|
dc.b @DJ_BUMP,%01010000 ; 33MHz WLCD (unreleased) <SM60>
|
|
dc.b @DJ_ORIG,%01000110 ; 25MHz Lego package (Centris 650)
|
|
dc.b @DJ_BUMP,%01010010 ; 33MHz Lego package (Quadra 650)
|
|
dc.b @DJ_BUMP,%01010110 ; 40MHz Lego package (Quadra 650 SpeedBump, unreleased) <SM60>
|
|
dc.b @DJ_ORIG,0 ; if here, this is EndOfTable
|
|
; VIA CPUID of 0 is a reserved (unused) machine.
|
|
|
|
; Configuration register values for SpeedBumped machines (by clock speed)
|
|
@BumpConfigTable
|
|
@bump20Config dc.w %0000000100000001 ; fastwr=1, ROMspeed=1
|
|
@bump25Config dc.w %0000000000011010 ; drpchg=1, drpw=1, ROMspeed=2
|
|
@bump33Config dc.w %0000000011111011 ; mhz33=1, drcpw=1, cyc2ta=1, drpchg=1 drpw=1, ROMspeed=4 <H24>
|
|
@bump40Config dc.w %0000001011111100 ; dwcpw=1, mhz33=1, drcpw=1, cyc2ta=1, drpchg=1, drpw=1, ROMspeed=5 <H22>
|
|
; <H35> <SM57>
|
|
@nodjMEMC ; <SM30> end
|
|
ENDIF ; <SM36> rb
|
|
|
|
; =======================================================================================================
|
|
; Pratt Configuration Register initialization <K4> thru next <K4>
|
|
; (Done here so that it isn't done multiple times in SizeMemPatch)
|
|
|
|
IF hasPratt THEN
|
|
IF isUniversal THEN ;
|
|
cmp.b #PrattDecoder,DecoderKind(a1) ; do we have a Pratt <SM27>
|
|
BNE.S @NotPratt ; IF we have a Pratt THEN
|
|
ENDIF ; { isUniversal }
|
|
|
|
MOVE.B #(1<<WhitneySWIMReset)|\; Clear the reset line to swim
|
|
(1<<WhitneyEnetReset)\ ; Clear the reset line to Sonic
|
|
,WhitneyPwrCtl ;
|
|
@NotPratt
|
|
ENDIF ; { hasPratt } <K4>
|
|
; =======================================================================================================
|
|
IF forRomulator THEN ; <T3>
|
|
TestInRAM a3 ; are we in RAM?
|
|
beq.s @notInRAM2 ;
|
|
movea.l d5,a3 ; get location of original VBR <T3>
|
|
movec USP,d5 ; retrieve original buserr value <T3>
|
|
move.l d5,BusErrVct(a3) ; and restore it in the exception table <T3>
|
|
movec a3,vbr ; restore vbr <T3>
|
|
@notInRAM2
|
|
ENDIF ; { forRomulator } <T3>
|
|
|
|
jmp (a4) ; all inited, return
|
|
|
|
ALIGN 16 ; <60><62> rb, for the 040 emulator...
|
|
|
|
dc.l 0,0,0,0 ; end of list
|
|
dc.l (GotBusError-BaseOfRom)+$40000000 ; alternate base of normal ROM <58> rb
|
|
dc.l (GotBusError-BaseOfRom)+$40800000 ; base of normal ROM
|
|
dc.l (GotBusError-BaseOfRom)+$00000000 ; base of overlay ROM
|
|
dc.l (GotBusError-BaseOfRom)+$FFC00000 ; base of NewWorld ROM?
|
|
|
|
GotBusError btst.l #beok,d7 ; indicate that bus error occured
|
|
move.l a5,a7 ; restore stack
|
|
rts6 ; return
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: InitVIAs aad8
|
|
; Inputs: A0 - Pointer to table of base addresses
|
|
; A1 - Pointer to ProductInfo record for this machine
|
|
; D0 - Flags indicating which base addresses are valid
|
|
; D1 - Flags indicating which external features are valid
|
|
; D2 - Bits 15..8, BoxFlag info (possibly unknown)
|
|
; D2 - Bits 7..0, Address Decoder Kind (zero if unknown)
|
|
; A6 - return address
|
|
;
|
|
; Outputs: None
|
|
;
|
|
; Destroys: A2,A3,D3
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Initializes the VIA1/VIA2/RBV direction, output and interrupt
|
|
; registers as well as general initialization of the VIAs.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
with DecoderInfo,ProductInfo
|
|
InitVIAs
|
|
btst.l #VIA1Exists,d0 ; see if we have VIA1
|
|
beq @VIA1done ; if not, skip it
|
|
|
|
movea.l VIA1Addr(a0),a2 ; get VIA base address <SM5> rb
|
|
movea.l a1,a3 ; get product info ptr <SM5> rb
|
|
adda.l VIA1InitPtr(a3),a3 ; point to the init info <SM5> rb
|
|
;
|
|
; This change is valid only for the Cyclone VIA1 Info Table...
|
|
; The other machine tables will have to be updated to follow this initialization
|
|
; or there will be problems. The DirA, BufA, and DirB, BufB regs have been Inited
|
|
; in a different order than in previous ROMS... THIS MUST BE UPDATED!!!!
|
|
; gjs ????
|
|
;
|
|
eieioSTP
|
|
move.b (a3)+,vBufA(a2) ; init output port A <P9> gjs
|
|
eieioSTP
|
|
move.b (a3)+,vDirA(a2) ; init direction for port A <P9> gjs
|
|
nop
|
|
eieioSTP
|
|
move.b (a3)+,vBufB(a2) ; init output port B <P9> gjs
|
|
eieioSTP
|
|
move.b (a3)+,vDirB(a2) ; init direction for port B <P9> gjs
|
|
nop
|
|
eieioSTP
|
|
move.b (a3)+,vPCR(a2) ; init peripheral control reg <SM7> rb
|
|
eieioSTP
|
|
move.b (a3)+,vACR(a2) ; init auxiliary control reg <SM7> rb
|
|
eieioSTP
|
|
move.b #$7F,vIER(a2) ; Disable all VIA interrupts. <SM7> rb
|
|
eieioSTP
|
|
|
|
@VIA1done
|
|
btst.l #VIA2Exists,d0 ; see if we have VIA2
|
|
beq.s @VIA2done ; if not, skip it
|
|
|
|
movea.l VIA2Addr(a0),a2 ; get VIA2 base address <SM4> rb, start
|
|
movea.l a1,a3 ; get product info ptr
|
|
adda.l VIA2InitPtr(a3),a3 ; point to the init info
|
|
|
|
IF hasPSC THEN ; <SM36> rb
|
|
btst.l #PSCExists,D0 ; Make sure we're on a Cyclone. <SM26>
|
|
Beq.s @NonPSC ; Not? Then do conventional init. <SM26>
|
|
|
|
|
|
Move.b PSCVIA2SInt(A2), D3 ; get PortA (slots) current values
|
|
eieioSTP
|
|
Or.b (A3)+, D3 ; or in via2 init info values
|
|
eieioSTP
|
|
Move.b D3, PSCVIA2SInt(A2) ; save new values
|
|
eieioSTP
|
|
Move.b #$7F, PSCVIA2IER(A2) ; disable all VIA2 interrupts.
|
|
eieioSTP
|
|
Move.b #$40, PSCVIA2IFR(A2) ; clear sound frame int.
|
|
eieioSTP
|
|
Bra.s @VIA2done ; this takes care of Cyclones
|
|
|
|
|
|
@NonPSC ; <SM4> rb, end <SM26>
|
|
ENDIF ; <SM36> rb
|
|
|
|
eieioSTP
|
|
move.b vBufA(a2),d3 ; get current values
|
|
eieioSTP
|
|
or.b (a3)+,d3 ; or in the default values
|
|
eieioSTP
|
|
move.b d3,vBufA(a2) ; init output port A
|
|
eieioSTP
|
|
move.b (a3)+,vDirA(a2) ; init direction for port A
|
|
nop
|
|
eieioSTP
|
|
move.b (a3)+,vBufB(a2) ; init output port B
|
|
eieioSTP
|
|
move.b (a3)+,vDirB(a2) ; init direction for port B
|
|
nop
|
|
eieioSTP
|
|
move.b (a3)+,vPCR(a2) ; init peripheral control reg
|
|
eieioSTP
|
|
move.b (a3)+,vACR(a2) ; init auxiliary control reg
|
|
eieioSTP
|
|
move.b #$7F,vIER(a2) ; Disable all VIA2 interrupts.
|
|
eieioSTP
|
|
|
|
; Simulate the Macintosh VBL interrupt by using timer 1 to output a square wave on PB7 of VIA #2.
|
|
; On NuMac, this output is tied to the CA1 pin of VIA #1 which is used for VBL on a Mac.
|
|
; Timer 1 causes the PB7 output to invert each time the counter reaches 0.
|
|
; There is an additional 2 tick delay while the VIA resets the counter. We get 783360 ticks/sec
|
|
; (Which is C16M/20). Mac VBL interrupt is 60.15 (C16M/(704*370)). The VIA responds on the
|
|
; negative edges only. So:
|
|
; timer 1 = (ticks/rate)/2 - 2
|
|
; = ((C16M/20)/(C16M/(704*370)))/2 - 2
|
|
; Note: VIA2 PB7 is not tied to anything on Waimea. JAWS generates this clock for us.
|
|
|
|
@T2Count equ ((704*370)/20)/2-2 ; VIA ticks per half-cycle
|
|
|
|
eieioSTP
|
|
move.b #@T2Count**$FF,vT1C(a2) ; Load low byte into counter/latch.
|
|
eieioSTP
|
|
move.b #@T2Count>>8,vT1CH(a2) ; Load high byte and off we go!
|
|
eieioSTP
|
|
@VIA2done
|
|
|
|
rts6
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: GetHardwareInfo ab4e
|
|
; Inputs: D2 - Bits 15..8, BoxFlag info (only if decoder kind <> 0)
|
|
; D2 - Bits 7..0, Address Decoder Kind (zero if unknown)
|
|
; A6 - return address
|
|
; A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: A0 - Pointer to DecoderInfo record for this machine
|
|
; A1 - Pointer to ProductInfo record for this machine
|
|
; D0 - Flags indicating which base addresses are valid 0-31
|
|
; D1 - Flags indicating which external features are valid 0-31
|
|
; D2 - Bits 31..16, hwCfgFlags info (possibly unknown)
|
|
; D2 - Bits 15..8, BoxFlag info (possibly unknown)
|
|
; D2 - Bits 7..0, Address Decoder Kind (zero if unknown)
|
|
;
|
|
; Destroys: A2, A5
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Determines the hardware configuration of this machine.
|
|
;
|
|
; NOTE: The 'beok' bit in D7 will always be cleared when this routine exits.
|
|
;
|
|
;_______________________________________________________________________
|
|
EXPORT FoundMatch ; <SM31>
|
|
|
|
with DecoderKinds,DecoderInfo,ProductInfo
|
|
GetHardwareInfo
|
|
|
|
; Use the new CPUID register scheme if supported on this CPU. (from GetHardwareInfoPatch)
|
|
|
|
bset.l #beok,d7 ; allow bus errors
|
|
movea.l a7,a5 ; mark the stack for bus error handler
|
|
|
|
IF hasCPUIDRegister THEN ; ; <SM24> rb <SM36> rb
|
|
movea.l a6,a1 ; save return address for GetHardwareInfo in a1
|
|
bsr6 GetCPUIDReg ; get CPUID register if it exists
|
|
movea.l a1,a6 ; restore return address for GetHardwareInfo
|
|
beq.s @foundCPUIDReg ; IF we don't have a CPUID register THEN
|
|
bra HasNoCPUIDReg ; ->CONTINUE in GetHardwareInfo using old recognition method <SM7> rb
|
|
@foundCPUIDReg ; ENDIF
|
|
|
|
|
|
cmpi.l #'Hnfo',([$68FFEFD0],$70) ; NKHWInfo.Signature, fix this later
|
|
bne.s @tryOldWay
|
|
import InfoNanoKernel
|
|
biglea InfoNanoKernel,a1
|
|
bra Matched
|
|
@tryOldWay
|
|
biglea CPUIDProductLookup-4,a2 ; get address of CPUID product lookup table
|
|
@MatchLoop ; LOOP (through product info entries to match CPU ID)
|
|
addq.w #4,a2 ; bump to next entry
|
|
move.l (a2),d1 ; see if end of list reached
|
|
beq UnknownCPU ; if we got to the end, we're severely hosed.
|
|
lea (a2,d1.l),a1 ; a1 := pointer to ProductInfo record
|
|
cmp.w CPUIDValue(a1),d0 ; see if product and CPU ID match
|
|
bne.s @MatchLoop ; if not, keep searching
|
|
|
|
btst #11,d0 ; is the complete CPU ID in the CPUID register?
|
|
beq Matched ; -> yes, we've got it
|
|
|
|
movea.l DecoderInfoPtr(a1),a0 ; get the pointer to this machine's decoder table
|
|
adda.l a1,a0
|
|
move.l DefaultBases(a0),d0 ; and get the default bases flags
|
|
|
|
IF hasYMCA THEN ; <SM36> rb
|
|
cmp.b #YMCADecoder,DecoderKind(a1) ; Do we have a YMCA controller <SM26> fau start
|
|
bne.s @GetVia ; No, go do the regular kind <SM26> fau end
|
|
|
|
Move.l DecoderAddr(a0),A1 ; Base of YMCA. <SM23> <SM26>
|
|
Move.l YMCA_CPUID0(A1),D0 ; Bit 0 of CPU ID. <SM23>
|
|
Move.l YMCA_CPUID1(A1),D1 ; Bit 1 of CPU ID. <SM23>
|
|
Rol.l #1,D0 ; Move to bit 0. <SM23>
|
|
And.b #1,D0 ; Only care about bit 0. <SM23>
|
|
Rol.l #2,D1 ; Move to bit 1. <SM23>
|
|
And.b #2,D1 ; Only care about bit 1. <SM23>
|
|
Or.b D1,D0 ; Complete ID. <SM23>
|
|
Move.l YMCA_CPUID2(A1),D1 ; Bit 2 of CPU ID. <SM23>
|
|
Rol.l #3,D1 ; Move to bit 1. <SM23>
|
|
And.b #4,D1 ; Only care about bit 1. <SM23>
|
|
Or.b D1,D0 ; Complete ID. <SM23>
|
|
Move.l YMCA_CPUID3(A1),D1 ; Bit 3 of CPU ID. <SM23>
|
|
Rol.l #4,D1 ; Move to bit 1. <SM23>
|
|
And.b #8,D1 ; Only care about bit 1. <SM23>
|
|
Or.b D1,D0 ; Complete ID. <SM23>
|
|
move.l (a2),d1 ; Get the relative offset to the ProductInfo record
|
|
lea (a2,d1.l),a1 ; and make it absolute
|
|
Cmp.b YMCAIdMatch(A1),D0 ; Do they match? <SM23>
|
|
|
|
Beq.s Matched ; Yes? Then let's get outta here. <P2>
|
|
Move.w CPUIDValue(a1),d0 ; Ack!!! We blew away D0 and it's needed in the MatchLoop loop, so
|
|
; we go and restore it. We are out of registers here.
|
|
Bra.s @MatchLoop ; No? Then try next product. <P2>
|
|
ENDIF ; hasYMCA <SM36> rb
|
|
|
|
@GetVia ; <SM4> rb, end
|
|
movea.l a6,a3 ; save return address for GetHardwareInfo in a1 <H16>
|
|
bsr6 GetVIAInputs ; read all of the VIA input lines into D1
|
|
movea.l a3,a6 ; restore return address for GetHardwareInfo <H16>
|
|
move.l (a2),d0 ; get the relative offset to the ProductInfo record
|
|
lea (a2,d0.l),a1 ; and make it absolute
|
|
and.l VIAIdMask(a1),d1 ; mask the VIA inputs
|
|
cmp.l VIAIdMatch(a1),d1 ; see if they match
|
|
beq.s Matched ; if so, you're done. else ... <H17><SM31>
|
|
movea.l a2,a3 ; save your place in the table in A3 <H17><SM31>
|
|
movea.l a6,a1 ; save return address for GetHardwareInfo in A1 <H17><SM31>
|
|
BSR6 GetCPUIDReg ; get CPU ID register value (again) <H17><SM31>
|
|
movea.l a1,a6 ; restore return address <H17><SM31>
|
|
movea.l a3,a2 ; restore our place in the table <H17><SM31>
|
|
bra.s @MatchLoop ; go look for another candidate to check <H17><SM31>
|
|
Matched ; END
|
|
bra.s FoundMatch ; yea!!! <SM7> rb
|
|
|
|
UnknownCPU bra.s UnknownCPU ; Ack!
|
|
|
|
ENDIF ; hasCPUIDRegister <SM24> rb <SM36> rb
|
|
|
|
HasNoCPUIDReg ; fall through to @MatchLoop
|
|
|
|
tst.b d2 ; check address decoder kind
|
|
beq FindDecoder ; if unknown decoder, search for it.
|
|
|
|
; The ProductKind and DecoderKind are setup in D2, find the matching ProductInfo record.
|
|
|
|
biglea ProductLookup-4,a0 ; point before the first product to check for
|
|
@MatchLoop addq.w #4,a0 ; point to next product to check for
|
|
move.l (a0),d0 ; see if end of list reached
|
|
beq FindDecoder ; if end, look start over, looking for decoder first
|
|
lea (a0,d0.l),a1 ; a1 := pointer to ProductInfo record
|
|
cmp.w ProductKind(a1),d2 ; see if product and decoder match
|
|
bne.s @MatchLoop ; if not, keep searching
|
|
|
|
FoundMatch
|
|
Move.L BasesValid1(A1), D0
|
|
BTst.L #$1E, D0
|
|
BEQ @skipAllThis
|
|
MoveA.L ([$68FFEFD0],$8), A0 ; NKHWInfo.UniversalInfoTableBase
|
|
Move.B $12(A1), D0
|
|
Move.B D0, $12(A0)
|
|
Move $14(A1), D0
|
|
Move D0, $14(A0)
|
|
Move.B $16(A1), D0
|
|
Move.B D0, $16(A0)
|
|
Move $10(A1), D0
|
|
Or D0, $10(A0)
|
|
MoveA.L (A0), A2
|
|
AddA.L A0, A2
|
|
Move.L $24(A1), D0
|
|
Or.L D0, $24(A0)
|
|
Or.L D0, -$1C(A2)
|
|
Move.L $28(A1), D0
|
|
Or.L D0, $28(A0)
|
|
Or.L D0, -$18(A2)
|
|
Move.L $2C(A1), D0
|
|
Or.L D0, $2C(A0)
|
|
Or.L D0, -$14(A2)
|
|
MoveA.L A1, A2
|
|
SubA.L A0, A2
|
|
Move.L A1, D0
|
|
MoveA.L $8(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $8(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $4(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $4(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $C(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $C(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $38(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $38(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $3C(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $3C(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $40(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $40(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $44(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $44(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $48(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $48(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $4C(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $4C(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $50(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $50(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $64(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $64(A0)
|
|
MoveA.L D0, A1
|
|
MoveA.L $5C(A1), A1
|
|
Tst.L A1
|
|
BEQ.B (* + $4)
|
|
AddA.L A2, A1
|
|
Move.L A1, $5C(A0)
|
|
MoveA.L D0, A2
|
|
MoveA.L A2, A1
|
|
Move.B $68(A1), D0
|
|
Move.L D0, $68(A0)
|
|
MoveQ.L #$0, D0
|
|
Move ([$68FFEFD0],$76), D0 ; NKHWInfo.CPU_ID
|
|
Move D0, $58(A0)
|
|
biglea CPUIDProductLookup,a2
|
|
Lea.L $8(A2), A2
|
|
Tst.L (A2)
|
|
BEQ.B @is_single_entry_table
|
|
Cmp.L (A2), D0
|
|
BNE.B (* + -$A)
|
|
Move.L $4(A2), D0
|
|
Bra.B @common_path
|
|
@is_single_entry_table
|
|
Move.L $60(A1), D0
|
|
@common_path
|
|
Move.L D0, $60(A0)
|
|
MoveA.L A0, A1
|
|
@skipAllThis
|
|
|
|
movea.l DecoderInfoPtr(a1),a0 ; get offset to DecoderInfo record
|
|
adda.l a1,a0 ; make it absolute
|
|
move.l BasesValid(a1),d0 ; get the base address valid flags
|
|
beq.s CheckBases ; we don't know for sure, so sniff around
|
|
bra CheckOptionals ; check for optional features (FPU) <8>
|
|
|
|
FindDecoder
|
|
move.l a6,d0 ; save return address in D0 for now
|
|
biglea DecoderLookup,a1 ; point to first table entry
|
|
CheckNextMap
|
|
movea.l a1,a0 ; get address of table entry
|
|
adda.l (a1)+,a0 ; a0 := pointer to DecoderInfo
|
|
movea.l CheckForProc(a0),a2 ; get offset to proc to check for this decoder
|
|
jmp (a0,a2.l) ; check for a this decoder
|
|
|
|
MapFound movea.l d0,a2 ; now save return address in A2
|
|
move.l DefaultBases(a0),d0 ; d0 := default bases valid flags
|
|
|
|
; an address decoder was found, now get all of the VIA inputs, to check for
|
|
; a match when multiple products share an address decoder.
|
|
|
|
bsr6 GetVIAInputs ; read all of the VIA input lines
|
|
movea.l a2,a6 ; restore the return address to A6
|
|
|
|
; The VIA inputs have been read into D1, now look for a matching product.
|
|
|
|
move.b AddrMap(a0),d2 ; get the address map to search for
|
|
biglea ProductLookup,a0 ; point before the first product to check for
|
|
@MatchLoop move.l (a0)+,d0 ; see if end of list reached
|
|
beq.s FindDecoder ; something is very wrong, and we don't have a clue
|
|
lea -4(a0,d0.l),a1 ; a1 := pointer to ProductInfo record
|
|
cmp.b DecoderKind(a1),d2 ; see if address decoders match
|
|
bne.s @MatchLoop ; if not, keep searching
|
|
move.l d1,d0 ; get the VIA inputs
|
|
and.l VIAIdMask(a1),d0 ; mask them
|
|
cmp.l VIAIdMatch(a1),d0 ; see if they match
|
|
bne.s @MatchLoop ; if not, try the next product
|
|
bra FoundMatch ; if found, return the info
|
|
|
|
|
|
CheckBases
|
|
move.l DefaultBases(a0),d0 ; get the default base flags
|
|
movea.l a6,a0 ; save return address
|
|
bclr.l #VIA2Exists,d0
|
|
beq.s @VIA2Done ; if not, don't test for one
|
|
movea.l DecoderInfoPtr(a1),a2 ; get offset to decoder info
|
|
movea.l VIA2Addr(a1,a2.l),a2
|
|
lea VIER(a2),a2 ; base address of VIA2 VIER register
|
|
@gotVIA2 ; <SM4> rb, end
|
|
bsr6 TestForVIER ; see if VIA2 exists
|
|
bne.s @VIA2Done ; if not found, no VIA2
|
|
bset.l #VIA2Exists,d0 ; has VIA2, set the bit
|
|
@VIA2Done
|
|
|
|
bclr.l #SCSIDMAExists,d0 ; see if SCSIDMA might be allowed
|
|
beq.s @SCSIDMADone ; if not, don't test for one
|
|
movea.l DecoderInfoPtr(a1),a2 ; get offset to decoder info
|
|
movea.l SCSIDMAAddr(a1,a2.l),a2
|
|
bsr6 TestForSCSIDMA ; see if SCSI DMA exists
|
|
bne.s @SCSIDMADone ; if not found, has regular SCSI
|
|
bset.l #SCSIDMAExists,d0 ; has SCSI DMA, set the bit
|
|
bclr.l #SCSIExists,d0 ; no regular SCSI
|
|
bclr.l #SCSIDackExists,d0 ; no SCSI DACK either
|
|
bclr.l #SCSIHskExists,d0 ; no SCSI Hardware Handshake either
|
|
@SCSIDMADone
|
|
|
|
; <58> rb, from Terror SCSI96AndRPUPatch <T9>
|
|
|
|
IF hasSCSI96 THEN ; <SM36> rb
|
|
bclr.l #SCSI96_1Exists, d0 ; see if 1st SCSI96 chip might be allowed
|
|
beq.s @SCSI96Done ; if not, don't test for one
|
|
movea.l DecoderInfoPtr(a1), a2 ; get offset to decoder info
|
|
movea.l SCSI96Addr1(a1,a2.l), a2 ; a2 <- SCSI96 base address
|
|
bsr6 TestForSCSI96 ; see if SCSI96 exists
|
|
bne.s @SCSI96Done ; if not found then some other SCSI hw
|
|
|
|
bset.l #SCSI96_1Exists, d0 ; has 1st SCSI96, set exists bit
|
|
bclr.l #SCSIDMAExists,d0 ; no SCSI DMA
|
|
bclr.l #SCSIExists,d0 ; no regular SCSI (5380)
|
|
bclr.l #SCSIDackExists,d0 ; no SCSI DACK
|
|
bclr.l #SCSIHskExists,d0 ; no SCSI Hardware Handshake
|
|
|
|
; Maybe we'll get lucky and fish another...
|
|
bclr.l #SCSI96_2Exists, d0 ; see if 2nd SCSI96 chip might be allowed
|
|
beq.s @SCSI96Done ; if not, don't test for one
|
|
movea.l DecoderInfoPtr(a1), a2 ; get offset to decoder info
|
|
movea.l SCSI96Addr2(a1,a2.l), a2 ; a2 <- SCSI96 base address
|
|
bsr6 TestForSCSI96 ; see if SCSI96 exists
|
|
bne.s @SCSI96Done ; if not found then some other SCSI hw
|
|
bset.l #SCSI96_2Exists, d0 ; has 1st SCSI96, set exists bit
|
|
@SCSI96Done
|
|
ENDIF ; <SM36> rb
|
|
|
|
movea.l a0,a6 ; restore return address
|
|
movea.l a1,a0 ; get product info pointer
|
|
adda.l DecoderInfoPtr(a0),a0 ; get decoder info pointer
|
|
|
|
CheckOptionals
|
|
move.l HwCfgWord(a1),d2 ; access hardware cfg flags <8>
|
|
|
|
; External features checked after CheckOptionals so that d1 can be used as a scratch register
|
|
CheckFeatures ; <11>
|
|
move.l ExtValid(a1),d1 ; get the external features valid flags <11>
|
|
bne.s @allDone ; know features, check for optional features <11>
|
|
move.l DefExtFeatures(a0),d1 ; get the default external features flags <11>
|
|
@allDone
|
|
bclr.l #beok,d7 ; disallow bus errors <1.7/8>
|
|
rts6 ; all done <8>
|
|
|
|
;_______________________________________________________________________ <SM17>
|
|
;
|
|
; Routine: GetExtHardwareInfo ab4e
|
|
;
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this machine
|
|
; A1 - Pointer to ProductInfo record for this machine
|
|
; D2 - Bits 15..8, BoxFlag info (only if decoder kind <> 0)
|
|
; D2 - Bits 7..0, Address Decoder Kind (zero if unknown)
|
|
; A6 - return address
|
|
; A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: A0 - Pointer to DecoderInfo record for this machine
|
|
; A1 - Pointer to ProductInfo record for this machine
|
|
; D0 - Flags indicating which base addresses are valid #32-63
|
|
; D1 - Flags indicating which external features are valid #32-63
|
|
; D2 - Bits 31..16, hwCfgFlags info (possibly unknown)
|
|
; D2 - Bits 15..8, BoxFlag info (possibly unknown)
|
|
; D2 - Bits 7..0, Address Decoder Kind (zero if unknown)
|
|
; D3 - Flags indicating which base addresses are valid #64-95
|
|
; D4 - Flags indicating which external features are valid #64-95
|
|
;
|
|
; Destroys: A2, A5
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Returns extended hardware information about the machine.
|
|
;
|
|
; NOTE: The 'beok' bit in D7 will always be cleared when this routine exits.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
GetExtHardwareInfo
|
|
|
|
bset.l #beok,d7 ; allow bus errors
|
|
movea.l a7,a5 ; mark the stack for bus error handler
|
|
|
|
move.l BasesValid1(a1),d0 ; get the base address valid flags for #32-63
|
|
bne.s CheckExtOptionals1 ; IF we don't know what bases are valid THEN
|
|
|
|
CheckExtBases1
|
|
move.l DefaultBases1(a0),d0 ; get the default base flags for #32-63
|
|
movea.l a6,a0 ; save return address
|
|
|
|
movea.l a0,a6 ; restore return address
|
|
movea.l a1,a0 ; get product info pointer
|
|
adda.l DecoderInfoPtr(a0),a0 ; get decoder info pointer
|
|
|
|
CheckExtOptionals1
|
|
;---------------
|
|
; Check for optional hardware devices for #32-63 here <SM17>
|
|
;---------------
|
|
|
|
|
|
move.l BasesValid2(a1),d3 ; get the base address valid flags for #64-95
|
|
bne.s CheckExtOptionals2 ; IF we don't know what bases are valid THEN
|
|
|
|
CheckExtBases2
|
|
move.l DefaultBases2(a0),d3 ; get the default base flags for #32-63
|
|
movea.l a6,a0 ; save return address
|
|
|
|
;---------------
|
|
; Call "TestForÉ" routines here to verify devices for #64-95 <SM17>
|
|
;---------------
|
|
|
|
movea.l a0,a6 ; restore return address
|
|
movea.l a1,a0 ; get product info pointer
|
|
adda.l DecoderInfoPtr(a0),a0 ; get decoder info pointer
|
|
|
|
|
|
CheckExtOptionals2
|
|
;---------------
|
|
; Check for optional hardware devices for #64-95 here <SM17>
|
|
;---------------
|
|
|
|
;----------------------------------------------------------------------------------------
|
|
; Check external features
|
|
;----------------------------------------------------------------------------------------
|
|
CheckExtFeatures ; <11>
|
|
move.l ExtValid1(a1),d1 ; get the external features valid flags <11>
|
|
bne.s @chkFeatures1 ; know features, check for optional features <11>
|
|
move.l DefExtFeatures1(a0),d1 ; get the default external features flags <11>
|
|
|
|
@chkFeatures1
|
|
|
|
;---------------
|
|
; Check for external features here for #32-63 <SM17>
|
|
;---------------
|
|
|
|
move.l ExtValid2(a1),d4 ; get the external features valid flags <11>
|
|
bne.s @chkFeatures2 ; know features, check for optional features <11>
|
|
move.l DefExtFeatures2(a0),d4 ; get the default external features flags <11>
|
|
|
|
@chkFeatures2
|
|
|
|
;---------------
|
|
; Check for external features here for #64-95 <SM17>
|
|
;---------------
|
|
|
|
@allDone
|
|
bclr.l #beok,d7 ; disallow bus errors <1.7/8>
|
|
rts6 ; all done <8>
|
|
|
|
|
|
|
|
IF hasGlue THEN ; <SM24> rb <SM36> rb
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: CheckForGLUE
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this decoder
|
|
; A1 - Pointer to next entry in DecoderLookup table
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: Jumps to MapFound if GLUE is detected
|
|
; Jumps to CheckNextMap if not a GLUE Decoder
|
|
;
|
|
; Destroys: D1, D2, A2, A6
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see a Mac II GLUE chip address decoder is present.
|
|
; A unique property of the GLUE chip is that it has a smaller
|
|
; I/O space, which repeats sooner than the other decoders in
|
|
; its class. So we check for VIA1 in it's normal place, and
|
|
; at the location that it will only wrap around with a GLUE
|
|
; decoder. If it is found in both places, then we assume that
|
|
; it is the GLUE chip decoder.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
EXPORT CheckForGLUE ; <SM36> rb
|
|
CheckForGLUE
|
|
movea.l VIA1Addr(a0),a2
|
|
lea vIER(a2),a2
|
|
move.l #$00020000,d2 ; GLUE chip wrap offset
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register
|
|
bne.w CheckNextMap ; if not, keep searching
|
|
bra.w MapFound ; it's a Mac II GLUE decoder
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasMDU THEN ; <SM36> rb
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: CheckForMDU
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this decoder
|
|
; A1 - Pointer to next entry in DecoderLookup table
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: Jumps to MapFound if MDU is detected
|
|
; Jumps to CheckNextMap if not a MDU Decoder
|
|
;
|
|
; Destroys: D1, D2, A2, A6
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see a MDU chip address decoder is present.
|
|
; We check to see that the VIA wraps at the correct place,
|
|
; and that it doesn't wrap earlier, where the GLUE chip would
|
|
; wrap. We also check to see if the RBV and VDAC can be accessed
|
|
; without a bus error, since the MDU generates the DSACK for them
|
|
; and they shouldn't bus error, even if they don't exist. An
|
|
; OSS decoder will bus error in MDUs RBV and VDAC address ranges.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
EXPORT CheckForMDU ; <SM36> rb
|
|
CheckForMDU
|
|
movea.l VIA1Addr(a0),a2
|
|
lea vIER(a2),a2
|
|
move.l #$00040000,d2 ; MDU chip wrap offset
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register
|
|
bne.w CheckNextMap ; if not, keep searching
|
|
sub.l #$00020000,d2 ; MDU VIA does not wrap at $20000
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register
|
|
beq.w CheckNextMap ; if so, keep searching
|
|
|
|
lea CheckNextMap,a6 ; if bus errors, not an MDU
|
|
movea.l RBVAddr(a0),a2
|
|
eieioSTP
|
|
tst.b (a2) ; RBV should never bus error
|
|
movea.l VDACAddr(a0),a2
|
|
eieioSTP
|
|
tst.b (a2) ; VDAC should never bus error
|
|
eieioSTP
|
|
bra.w MapFound ; it's a MDU decoder
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasOss OR hasFMC THEN ; <SM36> rb
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: CheckForOSSFMC
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this decoder
|
|
; A1 - Pointer to next entry in DecoderLookup table
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: Jumps to MapFound if OSS/FMC is detected
|
|
; Jumps to CheckNextMap if not a OSS/FMC Decoder
|
|
;
|
|
; Destroys: D1, D2, A2, A6
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see a OSS/FMC address decoder is present.
|
|
; We check to see that the VIA wraps at the correct place,
|
|
; and that it doesn't wrap earlier, where the GLUE chip would
|
|
; wrap. We also check to see if an OSS mask register exists,
|
|
; by trying to load it with priorities 1..6 (don't use 7, since
|
|
; if may cause a NMI to be generated).
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
EXPORT CheckForOSSFMC ; <SM36> rb
|
|
CheckForOSSFMC
|
|
movea.l VIA1Addr(a0),a2
|
|
lea vIER(a2),a2
|
|
move.l #$00040000,d2 ; OSS chip wrap offset
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register
|
|
bne.w CheckNextMap ; if not, keep searching
|
|
sub.l #$00020000,d2 ; OSS VIA does not wrap at $20000
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register
|
|
beq.w CheckNextMap ; if so, keep searching
|
|
|
|
lea CheckNextMap,a6 ; if bus errors, not an OSS
|
|
movea.l OSSAddr(a0),a2
|
|
move.b OSSMskFirst(a2),d1 ; save the old contents
|
|
lsl.w #8,d1 ; make room for temp use of low byte
|
|
moveq.l #6,d2 ; loop counter / data pattern
|
|
@OssLoop move.b d2,OSSMskFirst(a2) ; store a value (don't allow NMI=7)
|
|
TST.L AllOnes ; put $FFFFFFFF on the bus to scramble it <2>
|
|
move.b OSSMskFirst(a2),d1 ; read it back
|
|
andi.b #$07,d1 ; expect low bits to change
|
|
cmp.b d1,d2 ; see if they did
|
|
dbne d2,@OssLoop ; loop through all patterns
|
|
@Done lsr.w #8,d1 ; get saved value
|
|
move.b d1,OSSMskFirst(a2) ; restore it
|
|
tst.w d2 ; see if all patterns compared
|
|
bpl.w CheckNextMap ; if not, it's not an OSS chip
|
|
bra.w MapFound ; otherwise it's an OSS decoder
|
|
|
|
AllOnes dc.l $FFFFFFFF ; <2>
|
|
|
|
ENDIF ; <SM24> rb
|
|
|
|
IF hasVISADecoder THEN ; <SM36> rb
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: CheckForVISADecoder
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this decoder
|
|
; A1 - Pointer to next entry in DecoderLookup table
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: Jumps to MapFound if VISA decoder is detected
|
|
; Jumps to CheckNextMap if not a VISA Decoder
|
|
;
|
|
; Destroys: D1, D2, A2, A6
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see if a VISA address decoder is present.
|
|
; First, we check for a VIA IER at the correct address.
|
|
; If it is there, we check that it does not appear again
|
|
; at an offset of $00040000 in order to eliminate GLUE, MDU,
|
|
; and OSS, all of which wrap at this offset. We also check
|
|
; to see if the VISA (RBV) and VDAC can be accessed
|
|
; without a bus error, since the VISA generates the DSACK for them
|
|
; and they shouldn't bus error, even if they don't exist. An
|
|
; OSS decoder will bus error in VISAs RBV and VDAC address ranges.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
EXPORT CheckForVISADecoder ; <SM36> rb
|
|
CheckForVISADecoder
|
|
movea.l VIA1Addr(a0),a2 ; look for a VIA IER
|
|
lea vIER(a2),a2
|
|
bsr6 TestForVIER
|
|
bne.w CheckNextMap ; not found means can't be a VISA
|
|
|
|
move.l #$00040000,d2 ; other decoders wrap at this offset
|
|
bsr6 TestVIERWrap
|
|
beq.w CheckNextMap ; if it wraps, it's not a VISA
|
|
|
|
lea CheckNextMap,a6 ; if bus errors, not an MDU
|
|
movea.l RBVAddr(a0),a2
|
|
eieioSTP
|
|
tst.b (a2) ; VISA should never bus error
|
|
movea.l VDACAddr(a0),a2
|
|
eieioSTP
|
|
tst.b (a2) ; VDAC should never bus error
|
|
eieioSTP
|
|
bra.w MapFound ; if not, it's a VISA decoder
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasOrwell THEN ; <SM24> rb <SM36> rb
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: CheckForOrwell <13>
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this decoder <13>
|
|
; A1 - Pointer to next entry in DecoderLookup table <13>
|
|
; A5, A7, D7, VBR - setup for bus error handler <13>
|
|
;
|
|
; Outputs: Jumps to MapFound if Orwell is detected <13>
|
|
; Jumps to CheckNextMap if not an Orwell Decoder <13>
|
|
;
|
|
; Destroys: D2, A2 <13>
|
|
; Called by: BSR6 <13>
|
|
;
|
|
; Function: Checks to see an Orwell address decoder is present. We check to see<13>
|
|
; if we get a bus error when trying to access Orwell's I/O control <13>
|
|
; register I/O space. Orwell is the only decoder that doesn't bus <13>
|
|
; error in that part of I/O space. <13>
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
EXPORT CheckForOrwell ; <SM36> rb
|
|
CheckForOrwell
|
|
lea CheckNextMap,a6 ; return to decoder search if we bus error <19>
|
|
movea.l DecoderAddr(a0),a2 ; look for an Orwell <SM17>
|
|
move.l (a2),d2 ; Orwell won't bus error <13>
|
|
bra.w MapFound ; otherwise it is an Orwell decoder <13>
|
|
ENDIF ; <SM36> rb
|
|
|
|
IF hasJaws THEN ; <SM36> rb
|
|
;_______________________________________________________________________ <SM4> rb, start
|
|
;
|
|
; Routine: CheckForJAWS
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this decoder
|
|
; A1 - Pointer to next entry in DecoderLookup table
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: Jumps to MapFound if JAWS is detected
|
|
; Jumps to CheckNextMap if not a JAWS Decoder
|
|
;
|
|
; Destroys: D1, D2, A2, A6
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see a JAWS chip address decoder is present.
|
|
; By the time we get here we already know that the VIA does not
|
|
; wrap at $40000 or $20000, and that the RBV and VDAC addresses
|
|
; cause a bus error. Just to be safe though, we do some of the
|
|
; same VIA checks that were done before.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
EXPORT CheckForJAWS ; <SM36> rb
|
|
CheckForJAWS
|
|
movea.l VIA1Addr(a0),a2 ; Look for VIA wrap a various places
|
|
lea vIER(a2),a2
|
|
move.l #$00100000,d2 ; JAWS does wrap at $100000 <8> HJR
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register <8> HJR
|
|
bne.w CheckNextMap ; if so, keep searching <8> HJR
|
|
lsr.l #1,d2 ; JAWS doesn't wrap at $80000 <8> HJR
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register <8> HJR
|
|
beq.w CheckNextMap ; if not, keep searching <8> HJR
|
|
lsr.l #1,d2 ; JAWS doesn't wrap at $40000 <8> HJR
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register <8> HJR
|
|
beq.w CheckNextMap ; if so, keep searching
|
|
|
|
lea CheckNextMap,a6 ; now try the JAWS registers
|
|
movea.l JAWSAddr(a0),a2
|
|
tst.b (a2) ; JAWS should never bus error
|
|
bra.w MapFound ; it's a JAWS decoder
|
|
ENDIF ; <SM36> rb
|
|
|
|
|
|
IF hasNiagra THEN ; <SM36> rb
|
|
;_______________________________________________________________________ <H17> thru next
|
|
; <H17>
|
|
; Routine: CheckForNiagra
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this decoder
|
|
; A1 - Pointer to next entry in DecoderLookup table
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: Jumps to MapFound if Niagra is detected
|
|
; Jumps to CheckNextMap if not a Niagra Decoder
|
|
;
|
|
; Destroys: D1, D2, A2, A6
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see a Niagra chip address decoder is present.
|
|
; By the time we get here we already know that the VIA does not
|
|
; wrap at $40000 or $20000, and that the RBV and VDAC addresses
|
|
; cause a bus error. Just to be safe though, we do some of the
|
|
; same VIA checks that were done before.
|
|
;
|
|
;_______________________________________________________________________
|
|
Export CheckForNiagra
|
|
CheckForNiagra
|
|
movea.l VIA1Addr(a0),a2 ; Look for VIA wrap a various places
|
|
lea vIER(a2),a2
|
|
|
|
move.l #$FF200000,d2 ; Niagra doesn't wrap at $50100000
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register
|
|
beq.w CheckNextMap ; if not, keep searching
|
|
|
|
move.l #$00080000,d2 ; Niagra doesn't wrap at $00080000
|
|
bsr6 TestVIERWrap ; see if it is a VIA IER register
|
|
beq.w CheckNextMap ; if not, keep searching
|
|
|
|
lsr.l #1,d2 ; Niagra doesn't wrap at $40000
|
|
bsr6 TestVIERWrap ; Niagra if it is a VIA IER register
|
|
beq.w CheckNextMap ; if so, keep searching
|
|
|
|
lea CheckNextMap,a6 ; now try the Niagra registers
|
|
movea.l JAWSAddr(a0),a2
|
|
tst.b (a2) ; Niagra should never bus error
|
|
bra.w MapFound ; it's a Niagra decoder
|
|
; <H17> <SM4> rb,end
|
|
ENDIF ; <SM24> rb
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: CheckForUnknown aec6
|
|
; Inputs: A0 - Pointer to DecoderInfo record for this decoder
|
|
; A1 - Pointer to next entry in DecoderLookup table
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: Jumps to MapFound always.
|
|
;
|
|
; Destroys: D1, D2, A2, A6
|
|
; Called by: BSR6
|
|
;
|
|
; Function: This is the last decoder on the list of decoders to search,
|
|
; so if we get here, we can't identify the address decoder.
|
|
; We return to MapFound to indicate that this unknown decoder
|
|
; exists, but if we get here, we are really dead, and can't
|
|
; figure out enough to even try to tell someone about it.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
CheckForUnknown
|
|
bra.w MapFound
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: TestForVIER aeca, TestVIERWrap aecc
|
|
; Inputs: A2 - Address of the VIER register to test
|
|
; D2 - offset of alternate address to check for (wrap around)
|
|
; Used by TestVIERWrap, set to zero for TestForVIER.
|
|
; A6 - return address
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: ccr.z - 0 (bne) if not a valid VIER register, or bus error.
|
|
; - 1 (beq) if valid VIER register found.
|
|
;
|
|
; Destroys: D1
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see if the specified I/O register is a VIA IER
|
|
; (interrupt enable) register, by first setting all bits of
|
|
; the register, and then clearing each bit individually.
|
|
; Also checks to see if the same register also exists at an
|
|
; alternate address in I/O space, to detect specific address
|
|
; wrap around characteristics of some address decoders.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
TestForVIER ; A2 := address of VIER register to test
|
|
moveq.l #0,d2 ; D2 := wrap offset to test
|
|
TestVIERWrap ; A2 := address of VIER register to test
|
|
eieioSTP
|
|
tst.b (a2,d2.l) ; make sure wrap address can be accessed
|
|
eieioSTP
|
|
move.b (a2),d1 ; save old VIER value
|
|
eieioSTP
|
|
|
|
rol.w #8,d1 ; save it in the next byte
|
|
st.b d1 ; test pattern := $FF
|
|
move.b d1,(a2) ; set all bits of VIER
|
|
nop
|
|
eieioSTP
|
|
@loop neg.b d1 ; pattern of bit to clear
|
|
eieioSTP
|
|
move.b d1,(a2) ; clear the lowest order bit
|
|
nop
|
|
add.b d1,d1 ; shift the test pattern
|
|
beq.s @exit ; exit when all bits shifted out
|
|
neg.b d1 ; convert to mask of bits that should be set
|
|
eieioSTP
|
|
cmp.b (a2,d2.l),d1 ; see if they are set at the wrap address
|
|
eieioSTP
|
|
bne.s @exit ; if not, exit
|
|
cmp.b (a2),d1 ; see if they are set at the standard address
|
|
eieioSTP
|
|
beq.s @loop ; if so, keep testing
|
|
@exit ror.w #8,d1 ; get saved VIER value
|
|
eieioSTP
|
|
move.b #$7F,(a2) ; prepare to restore (clear all bits)
|
|
nop
|
|
eieioSTP
|
|
move.b d1,(a2) ; restore original VIER value
|
|
eieioSTP
|
|
lsr.w #8,d1 ; 0 if VIER found
|
|
rts6
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: TestForSCSIDMA aefe
|
|
; Inputs: A2 - Base address of SCSI DMA to test for.
|
|
; A6 - return address
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: ccr.z - 0 (bne) if SCSI DMA not found, or bus error.
|
|
; - 1 (beq) if valid SCSI DMA found.
|
|
;
|
|
; Destroys: none
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see if the specified I/O registers point to a
|
|
; SCSI DMA chip. Since the SCSI DMA chip generates it's own
|
|
; DSACK, a Bus Error may occur if it doesn't exist, which would
|
|
; cause this routine to return through the bus error handler,
|
|
; indicating that it doesn't exist. For now we just simply test
|
|
; to see if we can read the control register without getting
|
|
; a bus error. If we are successful, we assume that the chip
|
|
; exists. This test may need to be improved in the future.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
TestForSCSIDMA ; A2 := Base address of SCSI DMA to test
|
|
eieioSTP
|
|
tst.l $80(a2) ; try to read the control register
|
|
eieioSTP
|
|
cmp.b d1,d1 ; if no bus error, assume that it exists
|
|
rts6
|
|
|
|
|
|
; <58> rb, from Terror...
|
|
;_______________________________________________________________________ thru matching <T8>
|
|
;
|
|
; Routine: TestForSCSI96 af06
|
|
; Inputs: A2 - Base address of SCSI Port to test.
|
|
; A6 - return address
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: ccr.z - 0 (bne) if SCSI 5380 not found, or bus error.
|
|
; - 1 (beq) if SCSI 5396 found.
|
|
;
|
|
; Destroys: none
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Checks to see if we have a SCSI 5380 chip or the more advance
|
|
; SCSI 5394/5396 controller. The test is to access a register
|
|
; the 5394/5396 has that the 53c80 does not. An access to a non-existent
|
|
; address would cause us to BusError. Unfortunately, there is a possibility <T14>
|
|
; that a non-existent address is decoded by HW anyway so if we pass bus-err <T14>
|
|
; test we verify the contents of the regr with expected value for safety. <T14>
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
; the CMPI will be .NE. if the address we write to does not bus error, but is in <T14>
|
|
; reality, not there. So the CMPI above actually checks to see if the data stuck. <T14>
|
|
|
|
TestForSCSI96 ; A2 = Base address of SCSI port to test
|
|
eieioSTP
|
|
tst.b $c0(a2) ; try to read configuration #3 register (r/w)
|
|
eieioSTP
|
|
cmpi.b #$04, $c0(a2) ; ...verify data written in config. regr 3 <T14>
|
|
eieioSTP
|
|
rts6
|
|
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: GetVIAInputs af12
|
|
; Inputs: A0 - Pointer to Decoder Info record for this decoder
|
|
; D0 - DefaultBases flags for this decoder
|
|
; A6 - return address
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: D1 - Bits 31..24, inputs from VIA1, port A
|
|
; D1 - Bits 23..16, inputs from VIA1, port B
|
|
; D1 - Bits 15.. 8, inputs from VIA2, port A
|
|
; D1 - Bits 7.. 0, inputs from VIA2, port B
|
|
;
|
|
; Destroys: D2, A1
|
|
; Called by: BSR6
|
|
;
|
|
; Function: Reads the input ports for VIA 1 and 2 if they are supported
|
|
; by the current address decoder (which does not imply that
|
|
; they actually exist). If the are not supported, zeros will
|
|
; be returned, if they are supported, but do not exist, the results
|
|
; are unpredictable, but are most likely the value of a floating
|
|
; data bus. The values of the data direction registers are saved
|
|
; and restored, which makes this non-destructive.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
GetVIAInputs
|
|
moveq.l #0,d1 ; initialize via info result
|
|
btst.l #VIA1Exists,d0 ; see if VIA1 exists
|
|
beq.s @noVIA1 ; if not, skip it
|
|
movea.l VIA1Addr(a0),a1 ; get the VIA1 base address
|
|
|
|
eieioSTP
|
|
move.b vBufA(a1),d2 ; save port A
|
|
eieioSTP
|
|
|
|
lsl.w #8,d2 ; make room for direction bits
|
|
move.b vDirA(a1),d2 ; save direction bits
|
|
move.b d2,d1 ; get prior direction bits
|
|
eieioSTP
|
|
and.b AvoidVIA1A(a0),d1 ; if we need to avoid any output, don't make them input
|
|
eieioSTP
|
|
move.b d1,vDirA(a1) ; change bits to inputs
|
|
nop
|
|
eieioSTP
|
|
move.b vBufA(a1),d1 ; get port A inputs
|
|
eieioSTP
|
|
move.b d2,vDirA(a1) ; restore direction bits
|
|
lsr.w #8,d2 ; get saved port A
|
|
eieioSTP
|
|
move.b d2,vBufA(a1) ; restore port A
|
|
|
|
lsl.w #8,d1 ; make room for port B bits
|
|
eieioSTP
|
|
move.b vBufB(a1),d2 ; save port B
|
|
lsl.w #8,d2 ; make room for direction bits
|
|
eieioSTP
|
|
move.b vDirB(a1),d2 ; save direction bits
|
|
eieioSTP
|
|
move.b d2,d1 ; get prior direction bits
|
|
and.b AvoidVIA1B(a0),d1 ; if we need to avoid any output, don't make them input
|
|
eieioSTP
|
|
move.b d1,vDirB(a1) ; change bits to inputs
|
|
nop
|
|
eieioSTP
|
|
move.b vBufB(a1),d1 ; get port B inputs
|
|
eieioSTP
|
|
move.b d2,vDirB(a1) ; restore direction bits
|
|
eieioSTP
|
|
lsr.w #8,d2 ; get saved port B
|
|
move.b d2,vBufB(a1) ; restore port B
|
|
eieioSTP
|
|
@noVIA1
|
|
swap d1 ; VIA1 info to high word
|
|
btst.l #VIA2Exists,d0 ; see if VIA2 exists
|
|
beq.s @noVIA2 ; if not, skip it
|
|
eieioSTP
|
|
movea.l VIA2Addr(a0),a1 ; get the VIA2 base address
|
|
eieioSTP
|
|
|
|
move.b vBufA(a1),d2 ; save port A
|
|
eieioSTP
|
|
lsl.w #8,d2 ; make room for direction bits
|
|
move.b vDirA(a1),d2 ; save direction bits
|
|
eieioSTP
|
|
move.b d2,d1 ; get prior direction bits
|
|
and.b AvoidVIA2A(a0),d1 ; if we need to avoid any output, don't make them input
|
|
eieioSTP
|
|
move.b d1,vDirA(a1) ; change bits to inputs
|
|
nop
|
|
eieioSTP
|
|
move.b vBufA(a1),d1 ; get port A inputs
|
|
eieioSTP
|
|
move.b d2,vDirA(a1) ; restore direction bits
|
|
eieioSTP
|
|
lsr.w #8,d2 ; get saved port A
|
|
move.b d2,vBufA(a1) ; restore port A
|
|
eieioSTP
|
|
|
|
lsl.w #8,d1 ; make room for port B bits
|
|
move.b vBufB(a1),d2 ; save port B
|
|
eieioSTP
|
|
lsl.w #8,d2 ; make room for direction bits
|
|
move.b vDirB(a1),d2 ; save direction bits
|
|
eieioSTP
|
|
move.b d2,d1 ; get prior direction bits
|
|
and.b AvoidVIA2B(a0),d1 ; if we need to avoid any output, don't make them input
|
|
eieioSTP
|
|
move.b d1,vDirB(a1) ; change bits to inputs
|
|
nop
|
|
eieioSTP
|
|
move.b vBufB(a1),d1 ; get port B inputs
|
|
eieioSTP
|
|
move.b d2,vDirB(a1) ; restore direction bits
|
|
eieioSTP
|
|
lsr.w #8,d2 ; get saved port B
|
|
move.b d2,vBufB(a1) ; restore port B
|
|
eieioSTP
|
|
@noVIA2
|
|
rts6 ; all done
|
|
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; Routine: GetCPUIDReg afb4
|
|
;
|
|
; Inputs: A6 - return address
|
|
; A5, A7, D7, VBR - setup for bus error handler
|
|
;
|
|
; Outputs: ccr.z - 0 (bne) if CPUID reg not found or bus error.
|
|
; - 1 (beq) if CPUID reg found.
|
|
; D0.w - CPUID if CPUID reg found.
|
|
;
|
|
; Destroys: D0, D1, A2
|
|
;
|
|
; Function: Checks for the existance of a CPU ID register. If one is found, it checks to see
|
|
; if the value in the register matches the expected value for the current decoder
|
|
; type. The register is a long word located at $5FFFFFFC, and contains the following
|
|
; information.
|
|
;
|
|
; bits 31-16: signature $A55A
|
|
; 15-12: design center
|
|
; 0 = high volume
|
|
; 1 = portables
|
|
; 2 = high end Macintosh
|
|
; 3 = RISC
|
|
; 11: extension
|
|
; 0=complete ID appears in this register
|
|
; 1=supplemental ID appears in VIA or equivalent
|
|
; 10- 0: ID
|
|
;__________________________________________________________________________________________________
|
|
|
|
IF hasCPUIDRegister THEN ; <SM24> rb <SM36> rb
|
|
|
|
GetCPUIDReg
|
|
move.l ([$68FFEFD0],$70),d0 ; NKHWInfo.Signature
|
|
cmpi.l #'Hnfo',d0
|
|
bne.s @noHnfo
|
|
move ([$68FFEFD0],$76),d0 ; NKHWInfo.CPU_ID
|
|
bra @eq
|
|
@noHnfo
|
|
bra.s @ne
|
|
@eq
|
|
cmp d0,d0
|
|
@ne
|
|
rts6
|
|
|
|
ENDIF ; <SM24> rb
|
|
end
|
|
|