sys7.1-doc-wip/DeclData/PrimaryInit.a

3567 lines
154 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; File: RBVPrimaryInit.a -> PrimaryInit.a
;
; Written by: David Fung/Mike Puckett, October 9, 1988.
;
; Copyright: © 1988-1994 by Apple Computer, Inc. All rights reserved.
;
; Change History (most recent first):
;
; <SM25> 1/3/94 PN Throw out the extra MiniGamma record and eliminate IsUniversal
; conditions.
; <SM24> 12/13/93 PN Roll in KAOS and Horror to add support for Malcom and AJ
; <SM23> 11/9/93 KW add some srsrc's for STP
; <SM22> 11/8/93 JRH boxDBLite16 is now boxPowerBookDuo250. boxDBLite20 is now
; boxPenLite.
; <SM21> 8/17/93 SAM Put forSmurf conds around all the smurf junk.
; <SM20> 8/13/93 KW adding two more smurf wombats
; <SM19> 8/12/93 BG Removed boxWLCDc1 since it something that will never exist.
; Updated other boxflags to use the "official" names for released
; machines.
; <SM18> 8/11/93 KW adding some new smurf boxes to BivBoxTbl
; <SM17> 08-03-93 jmp Changed the reference names of the multiscan display constants
; to their new names.
; <SM16> 04-01-93 jmp Removed an extraneous Moveq instruction.
; <SM15> 01-19-93 HI Removed <SM14>. Other consequence of clearing scrnInval that
; I didn't know about which Mike Puckett related to me.
; <SM14> 01-19-93 HI Modified V8Init to invalidate the screen resource by clearing
; the scrnInval flag byte. This forces the Process Mgr to start
; up in color. Henceforth, if the PRAM is zapped, the machine
; starts up in color all the time. (Hoon Im)
; <SM13> 01-13-93 jmp Removed the extraneous MiniGamma record.
; <SM12> 01-11-93 jmp Updated to match latest HORROR sources.
; <SM11> 01-07-93 jmp Updated the V8Init so that it defaults to 4/8bpp when the video
; configurations change across reboots.
; <SM10> 12-23-92 jmp Removed the insidious non-VideoGuy font and cleaned up the
; BivBox jump table.
; <SM9> 12/23/92 RC Fixed Branch Bug
; <SM8> 12/23/92 RC Added support for Smurf on Wombat
; <SM7> 10-29-92 jmp (jmp,H72) Permanently enabled the “smart” PageMode for the
; DAFB-based CPUs.
; (jmp,H71) Added support for 33 MHz WLCD.
; <SM6> 10/28/92 SWC Changed VideoEqu.a->Video.a and ShutdownEqu.a->Shutdown.a.
; <SM5> 10-26-92 jmp Fixed the problems causing the assembler warnings showing up
; from HYs <SM4> check-in.
; <SM4> 10-25-92 HY Add support for BoxMacLCII boxflag.
; <SM3> 10-13-92 jmp Fixed a typo for the last check-in.
; <SM2> 10-13-92 jmp (jmp,H70) Optimized the no-connect cases in the DAFB monitor
; sensing & 'RNIN' code to NOT do table walks when we really
; “know” that nothing is connected.
; <SM1> 10/06/92 GDW New location for ROMLink tool.
; ———————————————————————————————————————————————————————————————————————————————————————
; Pre-ROMLink comments begin here.
; ———————————————————————————————————————————————————————————————————————————————————————
; <SM13> 09-29-92 jmp (jmp,H69) Added some code similar to that introduced in <H68>
; for the initial gamma-corrected white-black write.
; (jmp,H68) When initially writing R-G-B triples to the Antelope
; CLUT/DAC (Wombat/WLCD), added a > 5 PixClk delay to eliminate
; screen artifacts on NTSC displays.
; (jmp,H67) Added more support for the Antelope (AT&T/Sierra)
; CLUT/DAC used on Wombat/WLCD.
; <SM12> 09-03-92 jmp Cleaned up some comments in <SM11>.
; <SM11> 09-03-92 jmp Added CPU sResource support for 68020 (RISC emulators), and
; updated from Horror: (SWC,H66) Set default GSC video mode to 4
; bits/pixel instead of 2 for DBLite's FSTN display.
; (jmp,H65) Added initial support for the AT&T CLUT/DAC (Antelope)
; to be used in Wombat/WLCD systems.
; (jmp,H64) Conditionalized (with “forWombat”) the brain-dead
; parts of the NSC-8534 (the dot clock in Wombat/WLCD)
; initialization code, as it shouldnt be needed once the final
; parts are in place.
; (SWC,H63) Tweaked one register in the GSC initialization, and
; disabled GSC VBL interrupts (we'll use a Time Manager task
; instead to avoid cursor breakup).
; (SWC,H62) Hopefully now using the final GSC initialization
; values for DBLite's display.
; (ag,H61) Avoid talking to the power manager on non-niagra GSC
; machines.
; (jmp,H60) Corrected .s vs. non-.s branches and odd-alignment
; problems.
; (djw,H58) Fix bug in default bit depth writing to PRAM.
; (djw,H58) Change default screen depth for DBLite and Dart to
; 2-bit mode (a marketing decision).
; (ag,H57) Changed GSC GrayScale reg value to delay unblanking the
; screen until after gray screen.
; <SM10> 8/9/92 CCH Added delay between accesses to the National clock chip on
; machines that have them.
; <SM9> 07-14-92 jmp (SWC,H56) Fixed a trashed register in DBLiteInit.
; (HJR,H55) Install a BusError Handler when initializing the GSC,
; in order
; to detect whether a GSC is present or not. If a Bus Error occurs
; then Prune All resources and escape.
; (jmp,H54) Changed the Wombat/WLCD dot-clock initialization code
; to be more Cub-card friendly.
; (jmp,H53) Added a temporary “forRISC” conditional to mal-align
; the stack frame, which, for some reason, works correctly on the
; Cub card, but an aligned stack doesnt.
; (jmp,H52) Added in support to make the DAFB-related part of
; PrimaryInit
; work correctly among Spike, Eclipse, Zydeco, and all Wombat/WLCD
; CPUs.
; (SWC,H51) Power the GSC on/off depending on whether or not the
; LCD screen is being used.
; (SWC,H50) Updated the GSC initialization table with the latest
; skew and refresh register values from the hardware folks.
; (jmp,H49) Fixed the PrimFrame record to work better when the
; DAFB code is
; being run via the Cub card.
; (jmp,H48) Continued with DAFB/Wombat
; restructuring/optimizations; also, added a sync-on-green switch
; that maintains the sync-on-green state when switching among the
; AltSense sense codes.
; (jmp,H47) WombatDAFBs are not tied to the 040 reset
; instruction, so we
; need to reset the WombatDAFB registers every time we boot (for
; the other DAFB-based CPUs, this is not necessary).
; (jmp,H46) Disabled support for convolution for the Wombat
; version of DAFB.
; (jmp,H45) Added first-pass support for the Wombat version of
; DAFB.
; <SM8> 6/18/92 KW (jmp,H44) Eliminated yet even more of the old DAFBVidParams
; fields, so I adjusted the code accordingly. Also, extended the
; factory burn-in support for various display types for DAFB-based
; CPUs.
; <SM7> 6/4/92 KW (jmp,H42) Added support in the DAFBInit to work with the
; newly-compacted DAFB vidParams.
; (BG,H41) Changed various Wombat-style BoxFlag references to
; their new, more descriptive names.
; (jmp,H40) Eliminated support for the no-vRAM case in V8-based
; systems.
; (jmp,H39) Removed the VideoInfo patching from the V8Init.
; (HY,H38) Roll-in LC II changes. Fixed bug in routine "Blast"
; that caused the screen not to be grayed correctly on an LC/LC
; II. (was ADDA D3,A1)
; (jmp,H37) Conditionally dropped support for Apollo and removed
; the ugly VideoInfo patching from the DAFBInit.
; (HJR,H36) Updated GSCInitTable for TFT3Bit. It was incorrectly
; swapped with TFT4Bit.
; <SM6> 5/16/92 kc Roll in Horror Changes. Comments follow:
; <H35> 4/24/92 HJR Update the GSCInitTable with appropriate values.
; <H34> 4/22/92 SWC Changed which docking attribute to check in determining whether
; or not to use the built-in LCD screen on DBLite.
; <H33> 4/21/92 SWC Fixed <H32> so that the screen will be turned on if we're not
; connected to a docking station.
; <H32> 4/21/92 SWC In DBLiteInit, turn off the screen and backlight if we're
; connected to a docking station (the clamshell can't be open to
; see the screen).
; <H31> 4/16/92 SWC In DBLiteInit, made GSC initialization based on the display ID
; so we correctly handle the case of normal/inverted display, etc.
; <H30> 4/3/92 SWC Modified the V8 and DAFB setup code to be more tolerant of
; additions to the ProductInfo record (I had added a new field to
; the end and found that it wasn't being copied correctly when the
; ProductInfo record is cloned into the system heap).
; <H29> 3/17/92 HJR Fix equate error where _Unimplemented was set to A895 instead of
; A89F.
; <H28> 3/17/92 SWC Renamed boxDBLite->boxDBLite25 and boxDBLiteLC->boxDBLite33, and
; added boxDBLite16 and boxDBLite20 to the primary init and sRsrc
; pruning lists.
; <H27> 3/6/92 SWC Disable the video driver if we're in a docking station on
; DBLite.
; <H26> 02/19/92 jmp Changed the remaining Condor references to Wombat.
; <H25> 2/17/92 SAM Changed boxCondor to boxWombat.
; <H24> 01/27/92 jmp (jmp,Z31) The no-connect path now no longer supports the
; alternate sense byte. Now, only type-6s trigger it.
; <H23> 01/27/92 jmp (jmp,Z30) Fixed a problem I introduced in <Z29> where I would
; cause Zydeco to hang if nothing was plugged into built-in video.
; <H22> 01/22/92 jmp (jmp,Z29) Updated the original “No Connect” code to take full
; advantage of the newly-defined extended sense codes. Changed
; the name from “NoConnect” to “AltSense.”
; <H21> 1/16/92 SWC Removed a bit too much extraneous code from DBLiteInit in <H19>.
; <H20> 1/14/92 SWC Updated boxFlag labels to use shipping product names.
; <H19> 1/13/92 SWC Removed code to test for GSC in DB-Lite's primary init since all
; systems now have a GSC. Pulled the panel interrupt disable from
; <H14> since the driver now uses panel interrupts. Added DB-Lite
; LC to the primary init list.
; <H18> 01/11/92 jmp Did some code clean-up, and added rudimentary support for the
; newly-defined extended sense codes.
; <H17> 12/17/91 jmp Updated the UnivAdjust code in the DAFB section to reflect the
; newly added VideoInfo record (for Kong and Vesuvio) in the
; Universal tables.
; <H16> 12/16/91 HJR Added support for Dartanian.
; <H15> 12/12/91 jmp Added support for DBLiteLC.
; <H14> 12/12/91 SWC Temporarily disable LCD panel interrupts for DB-Lite (in
; DBLiteInit) until the driver is ready to support them.
; <H13> 12/10/91 HJR Changed adda.w to adda.l since value was sign extended into a
; negative number. Fixed some indirection in Universal tables and
; PanelAdjust in DBLite for proper Black on White.
; <H12> 11/26/91 jmp Added VERY preliminary support for DB-Lites GSC.
; <H11> 11/25/91 jmp Updated the DAFB PrimaryInit to look in the board sRsrc for the
; vidParams instead of the functional sRsrc.
; <H10> 11/12/91 jmp Added a table of DAFB default modes. These are used to
; determine the depth to default to depending on the size of vRam.
; <H9> 11/06/91 jmp Instead of using the extended-sense monIDs for DAFB, I now just
; use the indexedSense monIDs so that every ID is unique. This
; works out better for the no-connect code.
; <H8> 11/05/91 jmp Added support for 19” Displays for DAFB-based CPUs.
; <H7> 11/01/91 jmp Added minimal support for doing both grayscale and
; black/white-only LCD displays on DBLite. For now, only the
; black/white entry is applicable.
; <H6> 10/31/91 jmp Marketing (Ross Ely) finally admitted that defaulting to the
; 6500°K gamma table for Vesuvio & GoldFish was a bad idea, so I
; am now defaulting to the 9300°K gamma table on those displays.
; Yeah!
; <H5> 10/29/91 jmp Changed the Spike33 names to Condor.
; <H4> 10/24/91 jmp Update the UniversalAdjust code to accomodate the new
; ClockPRAMPtr entry.
; <H3> 10/24/91 jmp Updating to Zydeco-TERROR version.
; <H2> 10/22/91 SWC Changed MSCExists to MSCChipBit since MSC is an RBV variant.
; <SM5> 4/7/92 JSM Dont define boxMacIIci and boxMacIIfx here anymore. This
; reflects the version checked into Reality.
; <SM4> 3/31/92 JSM Rolled this file into Reality.
; <SM3> 2/14/92 kc Remove "If isUniversal Then".
; <SM2> 2/11/92 RB Got rid of damn warnings. Changed boxFlags used.
; <29> 01/20/92 jmp Updated the original “No Connect” code to take full advantage of
; the newly-defined extended sense codes. Changed the name from
; “NoConnect” to “AltSense.”
; <28> 01/09/92 jmp Did some code clean-up, and added rudimentary support for the
; newly-defined extended sense codes.
; <27> 12/17/91 jmp Update the UnivAdjust code in the DAFB section to reflect the
; newly added VideoInfo record (for Kong and Vesuvio) in the
; Universal tables.
; <26> 11/08/91 jmp Added a table of DAFB default modes. These are used to
; determine the depth to default to depending on the size of vRam.
; <25> 11/06/91 jmp Instead of using the extended-sense monIDs for DAFB, I now just
; use the indexedSense monIDs so that every ID is unique. This
; works out better for the no-connect code.
; <24> 11/05/91 jmp Added 19” Display support for DAFB-based CPUs.
; <23> 10/31/91 jmp Marketing (Ross Ely) finally admitted that defaulting to the
; 6500°K gamma table for Vesuvio & GoldFish was a bad idea, so I
; am now defaulting to the 9300°K gamma table on those displays.
; Yeah!
; <22> 10/23/91 jmp Started using BoxFlag instead TestFor for distinguishing CPUs
; with built-in video due to the fact that several of the TestFor
; flags (especially for machines having RBV) were starting to
; collide.
; <21> 10/22/91 jmp Added code to prevent the PAL encoder box extended sense line
; code to not collide with the Vesuvio indexed sense line code
; (i.e., they are both zero).
; <20> 09/13/91 jmp Added support for 16pp on Rubik displays when only 512K of vRAM
; is around in preparation for Spike33s.
; <19> 8/26/91 jmp Added support for a Spike33-type box.
; <18> 8/21/91 jmp Changed all the Eclipse33 references to Zydeco.
; <17> 8/9/91 jmp Fixed a problem with NTSC & PAL family modes where changing the
; amount of vRAM didnt cause DAFBs part of PrimaryInit to
; re-validate the SP_LastConfig pRAM byte. Also, fixed a problem
; where the has16bppSRsrc pRAM bit (for DAFB) was not being set
; properly.
; <16> 8/7/91 jmp Added 16bpp support for all applicable DAFB displays.
; <15> 7/29/91 jmp Wasnt correctly determining the installed amount of vRam for
; DAFB 16bpp modes. Also, wasnt correctly setting up the CLUT
; for mono-only displays; should have only been writing to the
; blue channel. Finally added the Eclipse33 (Zydeco) & TIM-LC
; sRsrc-prunning identifiers to the appropriate tables.
; <14> 7/13/91 jmp Added code to extend the factory burn-in no-connect detection
; code so that ANY display supported by DAFB could be used.
; <13> 7/11/91 jmp Added code to more intelligently handle the enabling & disabling
; of page mode for DAFB.
; ———————————————————————————————————————————————————————————————————————————————————————
; Pre-Zydeco ROM comments begin here.
; ———————————————————————————————————————————————————————————————————————————————————————
; <12> 6/29/91 jmp Added support for the alternate AC842A-compatible timing adjust,
; horizontal active line, and horizontal fron porch DAFB
; parameters.
; <11> 6/27/91 jmp Now automatically turn on16bpp if running on a machine equipped
; with an AC842A, clocked at 33Mhz, controlled by a DAFB 3, having
; 2 Megs of vRam, and hooked up to a Vesuvio or RGB Portrait
; display.
; <10> 6/26/91 jmp Rewrote the ACDC-whacking code to be more AC842A (AMD) friendly.
; <9> 6/25/91 jmp Fixed a problem where I was incorrectly assuming that if I could
; see bank 3 of vRam (on a Spike or Eclipse), that bank 2 must be
; installed. This was wrong.
; <8> 6/24/91 jmp Added support for 16bpp Vesuvio & RGB Portrait displays.
; <7> 6/17/91 jmp Updated DAFBs VideoInfo handler for NTSC, PAL, SuperVGA,
; GoldFish, Kong, and Vesuvio. I had to do this because Mitsubish
; VRams perform a little differently from the Toshiba VRams.
; Also, it turns out that defaulting to sync-on-green disabled for
; VGA is bad in that some third-part cables (namely Sonly for
; their CPD-1302) expect that sync-on-green will be enable in that
; they do not connect the H- and V-Sync lines. This, of course,
; is wrong, but we should support them. Ugh!
; <6> 6/7/91 jmp For Rubik & VGA, defaulted to disabling sync-on-green.
; <5> 6/4/91 jmp Changed the mini gamma table to reflect the fact that the RGB
; Portrait gamma table is now pointed to the HR gamma directory
; instead of the one used by Vesuvio & Goldfish (where it was
; originally pointed to).
; <4> 5/25/91 jmp Shut off Swatch (video sync) in the PrelimInit table for DAFB to
; eliminate visual artifacts during boot.
; <3> 5/24/91 jmp Added support for enabling/disabling sync-on-green. Also,
; updated the initial DAFB params to use the VGA clock because
; several third-party displays only use the VERY first clock they
; get. Ugh.
; <2> 5/22/91 jmp Eliminated the conditionals on the DB-Lite entry point, and
; moved it ahead of the RBV entry point because RBV exists on
; DB-Lite.
; <1> 5/22/91 jmp Changed name to PrimaryInit.a from RBVPrimaryInit.a to reflect
; the fact that this file is used by all built-in videos, not
; just RBV.
; <24> 5/15/91 jmp Added DB-Lite support. For now, though, the entry part of code
; is conditionalized out (i.e., “If 0 Then”).
; <23> 5/10/91 jmp Optimized the grayscreen code for the NTSC & PAL safetitle modes
; by loading IndexedBlack into a register. Added SuperVGA
; support. Now check for 25 vs. 33 MHz CPU operation the new,
; better way. Made the generalized grayscreen code (“Blast”) more
; universal by switching into 32-bit mode (e.g., DB-Lites
; framebuffer is in a 32-bit address space). Code review changes:
; Removed all the UnivInfoPtr stuff to get BoxFlag; now just get
; it from lo-mem; tightened up the CPU-sRsrc prunning code.
; <22> 4/26/91 jmp Updated the UnivInfoPtr-Adjust code for the new PAL convolved
; baseAddr offset.
; <21> 4/25/91 jmp We can actually do NTSC & PAL convolved in 1MB vRam, so I
; updated the family mode stuff accordingly. Thus, only 512K
; Spikes will not see families -- i.e., theyll have
; interlaced-only versions of NTSC & PAL available.
; <20> 4/23/91 jmp For NTSC & PAL, started defaulting to the convolved modes when
; enough VRam is available. It should be noted that this update
; will hose DAFB 1 machines, but ultimately its the right thing
; to do. Also, had to update the UnivInfoPtr because of the new
; SndControlPtr field. Finally, I was actually doing the
; UnivInfoPtr adjust too soon; i.e., needed to wait until we know
; how which family member was going to be used because the
; baseAddr could be different.
; <19> 4/19/91 jmp Fixed a bug in Blast where D2 was supposed to contain the
; skip-fact value, but D1 was actually being used. Luckily, D1
; always happened to be zero, which is the standard skip factor;
; would have blown up on an LC in the VGA & mode-560 stuff. Also,
; added gamma correction code (3-channel) due to the 6500°K
; simulation for Vesuvio & GoldFish.
; <18> 4/5/91 jmp Eliminated a deadly call to _DisposPtr. Also, updated the DAFB
; PrelimInit params to be less harsh (i.e., the first screen clear
; doesnt bounce as much).
; <17> 4/1/91 jmp Removed support for DAFB 1.
; <16> 3/25/91 jmp After reading the sense lines, I now save the true monID in the
; vendorUse4 field of Slto pRam. I need to do this for the driver
; for gamma-correction purposes. Also, I was not invalidating the
; 'scrn' resoruce when the current display configuration did not
; match pRam. This caused the “Welcome to Mac” screen to act
; weird on restart from switches between family configurations.
; <15> 3/18/91 jmp Fixed non-contiguous vRam problem. Set factory burn-in display
; to be an HR instead of the Rubik per DAF. Fixed “false” tops
; and bottoms on convolved screen-clearing code.
; <14> 3/4/91 jmp Fixed 1bpp Rubik Display problem (i.e., first line of vRam not
; being cleared). Added factory burn-in support (same as for LC).
; <13> 2/25/91 jmp Just cleaned up some comments.
; <12> 2/15/91 jmp Added code to disable interrupts in ApolloInit. Added
; sRsrc_BdApollo to spIDTable. Restructured to look more
; universal (i.e., things dont jump into and out of the RBV part
; of the code anymore). Fixed screen graying code (including CLUT
; intialization) to work properly with the convolved modes
; starting at 4bpp. Conditionalized this so that if/when new
; DAFBS are around the coding effort will be minimal. Shut
; everything down when no-connect is detected. Added check for 33
; vs. 25 Mhz operation.
; <11> 2/10/91 jmp Needed to skip past Misc params for restart sequence. Updated
; PrelimInit table to contain spacer (blanks) for Misc params.
; Added NTSC and PAL encoder box codes to the extended sence code
; mapping. Updated the mapping for GoldFish.
; <10> 2/3/91 jmp Adjusted pref/family mode table so that Rubiks can do 32bpp in
; 1 Megs of vRam. Adjusted pref/family mode table so that NTSC
; and PAL have family modes. Updated the grayscreen code for ST
; modes (including blacking around the sides). Put extended
; senseline code inline. Added pruning code for 030 vs. 040 CPU
; families.
; <9> 1/31/91 JK Added code to reset Sonic.
; <8> 1/30/91 jmp Lots of changes: Added the extended sense line code. Added
; entries for VGA, PAL, and Goldfish in the DAFB pref/family mode
; table. Replaced inline reset code with macro from
; RBVDepVideoEqu.a. Temporarily disabled family modes for NTSC
; and PAL because we dont have the data yet. Updated the
; pref/family mode table for Rubik due to having to lengthen
; rowbytes in 1-8bpp mode (to fix the jittering 1bpp mode).
; <7> 1/24/91 jmp Added support for extended-sense-line displays. Next check-in
; should complete the extended-sense-line algorithm.
; <6> 1/21/91 jmp Added funny code for patching the universal table for Kong (and
; eventually Goldfish and NTSC and PAL) support.
; <4> 1/15/91 DAF Added tons of code for support of DAFB video, SONIC Ethernet,
; and general touch-up
; <4> 1/15/91 DAF Added a ton of code for support of DAFB video, SONIC pruning and
; general touch ups.
; <3> 12/11/90 JJ Mac LC: Changes references to VISAChipBit to V8ChipBit.
; <2> 12/11/90 HJR Integration of V8 and Tim video into Terror build.
; <6> 6/12/90 JJ Add support for Elsie Apple II emulation video modes.
; <5> 4/30/90 JJ Minor formatting changes.
; <4> 4/30/90 JJ Added multiple monitor support for Elsie and Erickson.
; {4} 4/19/90 DAF Improved video mode family support for Erickson, added video
; mode family support for Elsie, added Waimea support, added
; multi- board sRsrc support.
; <3> 4/9/90 JJ Rolling in changes from Reality. Original comments below.
; {3} 4/3/90 DAF Added universal VISA/Elsie support
; <2> 2/15/90 CV Rolling in changes from Reality. Original comments below
; {2} 2/14/90 DAF Updated to support multiple built-in video CPUs. Added Elsie
; primaryInit.
; <2.7> 7/17/89 CSL Fixed bug in reading first entry to BootGlob, swap to 32 bit
; addressing mode before access.
; <2.6> 7/11/89 DAF FOR AURORA BUILD - Included code review changes; added 16/25MHz
; detect flag word, reorganized screen graying determinations,
; simplified the memory sizing test.
; <2.5> 7/11/89 DAF FOR AURORA BUILD - Updated header equate names
; 7/11/89 DAF Rolled in code review changes- 1) Fixed memory size test. Added
; test of flag word for presence of built-in video hw.
; <2.3> 6/30/89 DAF Removed dynamic configuration determination. Now everything keys
; off of the Universal structures
; <2.4> 6/30/89 CSL Added an additional test for presence of bank A video frame
; buffer. If there isn't any memory, then deactivate video
; 6/29/89 DAF Added board and CPU sRsrc determination and pruning. Removed
; dynamic video configuration- capabilities are keyed off of
; BoxFlag (sorry Aurora16 owners). Real support of the SE display
; is also included (THIS FEATURE IS NOT TESTABLE).
; <2.2> 6/11/89 GGD Get Frame Buffer base from ROM tables.
; <2.0> 5/15/89 DAF Fixed Universal ROM support for non-RBV machines
; <2.1> 5/15/89 DAF Fixed the infamous "clearing the screen, even when it's not
; there" bug
; 5/15/89 DAF Fixed bug in sRsrc delete code for Universal ROM.
; <•1.9> 5/15/89 DAF Restructured to improve support for 1MB and 16MHz machines.
; Added video mode families. Added universal ROM support.
; Corrected a number of bugs with scrn resource invalidation.
; 5/8/89 DAF Massive updates. Restructured sRsrc lists handling. Reordered
; identification. Added video default shifting. Fixed some pRAM
; problems that were nuking scrn resources.
; 4/15/89 DAF A number of updates. Added support for 1MB CPU RAM modes
; Corrected dead internal video error. Use VIA2RBV equate for
; universal ROMs.
; <•1.7> 4/15/89 DAF Added 1MB CPU RAM sRsrc support. Fixed dead onboard video
; problems.
; <1.6> 3/6/89 GGD Changed RBV register usage now that equates are offsets from
; RBVBase, instead of being absolute addresses.
; <1.5> 2/27/89 DAF Removed A/UX1.0 support (won't ever be needed), updated scrn
; resource invalidation, modified sRsrc list pruning to improve
; support for NuBus video only
; 2/27/89 DAF Fixed three things- 1) Removed A/UX sRsrc support 2) updated
; scrn resource invalidation 3) modified sRsrc list pruning to
; better support NuBus video only (if internal video deactivated,
; then return failed seStatus so driver is not opened and
; interrupts don't get enabled. This last one is done by removing
; SE monitor support temporarily (since it's ID is the same as no
; monitor).
; <1.4> 2/21/89 djw renamed sSetsRsrcState to SetsRsrcState
; <1.3> 2/1/89 DAF Improved support for 16MHz Spin and SE displays.
; 1/30/89 DAF Added support for 16MHz Spin and SE monitors.
; <1.2> 11/17/88 DAF Updated to set vDACPixMask
; <1.1> 11/14/88 DAF Added temporary conditional for emulator development (disables
; CPU clock rate check)
; <1.0> 11/11/88 DAF Adding to EASE for the first time.
; 10/9/88 DAF New today
;
;-------------------------------------------------------------------
STRING C
PRINT OFF
LOAD 'StandardEqu.d'
INCLUDE 'DockingEqu.a'
INCLUDE 'EgretEqu.a'
INCLUDE 'GestaltEqu.a'
INCLUDE 'GestaltPrivateEqu.a'
INCLUDE 'HardwarePrivateEqu.a'
INCLUDE 'IOPrimitiveEqu.a'
INCLUDE 'PowerPrivEqu.a'
INCLUDE 'ROMEqu.a'
INCLUDE 'Video.a'
INCLUDE 'SlotMgrEqu.a'
INCLUDE 'ShutDown.a'
INCLUDE 'SonicEqu.a'
INCLUDE 'UniversalEqu.a'
INCLUDE 'DepVideoEqu.a'
PRINT ON
SEG '_sPrimaryInitRec'
MACHINE MC68020
;=====================================================================
; Header
;=====================================================================
LPrimaryInit PROC
DC.B sExec2 ; code revision
DC.B sCPU68020 ; CPU type is 68020
DC.W 0 ; reserved
DC.L Begin-* ; offset to code
;=====================================================================
;PROCEDURE PrimaryInit(Slot:sInteger_8; VAR VendorStatus,Status:sInteger_16);
;=====================================================================
WITH seBlock,spBlock
PrimFrame RECORD {A6Link},DECREMENT
return DS.L 1 ; return address
A6Link DS.L 1 ; placeholder for link
spBlk DS SpBlock ; spBlock for generic use
sPRAMBlk DS.B SizesPRAMRec ; spRAMRec for generic use
VidDefBlk DS.B 2 ; parameter block for SetVideoDefault
IsSlowClock DS.B 1 ; if SlowClock CPU=1, else =0
saveMMUMode DS.B 1 ; save the entering MMU mode <4>
vidParamsPtr Ds.l 1 ; ptr to video params <10>
vRAMBaseAddr Ds.l 1 ; ptr to vRAM base address
monID Ds.b 1 ; saved monID <16>
has16bppACDC Ds.b 1 ; For DAFB, true when ACDC == AC842A.
hasLin16bppCLUT Ds.b 1 ; For DAFB, true when ACDC == Antelope.
wombatDAFB Ds.b 1 ; For DAFB, true when on a WombatDAFB.
clkSetup Ds.b 1 ; For DAFB, true when we dont need to reset various clock bits.
sogSwitch Ds.b 1 ; For DAFB, true when we should leave sync-on-green alone.
altSenseEnb Ds.b 1 ; For DAFB, true if we were AltSenseing LAST reboot.
disableLCD Ds.b 1 ; For DBLite, true if we're in a docking station <H27>
LocalSize EQU * ;
ENDR
DT_Size Equ $08 ; Size (in bytes) of entries in DAFB table.
MT_Size Equ $04 ; Size (in bytes) of entries in Mode table.
BivTbl Record 0 ; Built-in Video BoxFlag/Offset table.
bivBox Ds.w 1 ; BoxFlag identifier.
bivOffset Ds.w 1 ; Offset to appropriate code.
Endr
;=====================================================================
WITH PrimFrame
Begin
;
; Set initial vendor status
;
LINK A6,#LocalSize ; allocate some space for locals
MOVE.W #seSuccess,seStatus(A0) ; this PrimaryInit always succeeds
; Perform some generic initialization
CLR.B spBlk.spSlot(A6) ; this is always a slot zero primaryInit
CLR.B spBlk.spExtDev(A6) ; external device = 0
MOVE.W #$0080,VidDefBlk(A6) ; if built-in video becomes active, we will
; set the default to slot zero, mode $80
;
; The _sReadDrvrName slot manager routine (lamely) returns the board name of the device, rather than
; anything directly related to the functional sRsrc list. Since the universal ROM would only normally
; have one board sRsrc list, all CPU variants using this ROM would have to have the same “driver name.”
; This isn't a big deal since each machine can be identified by ID codes, but Monitors displays
; the board name in the Options dialog, as well as using this name to load extension files.
; We correct this (in standard hack-looking slot wrangler style) by including multiple board sRsrcs,
; then deleting the unneeded ones. Only the Mac II variant of the board sRsrc includes a PrimaryInit
; since this code takes care of all CPU variants in the Universal ROM.
;
LEA spIDTbl,A1 ; get pointer to table of possible spIDs
CLR.W D0 ; clean up this register
Move.b BoxFlag,D1 ; Get the BoxFlag for this machine.
ADDQ #BoardspIDShift,D1 ; shift off of box flag base
LEA spBlk(A6),A0 ; point A0 to the spBlock
; If this is the first time thru, the Slot Manager can't tell which boardID is the correct one to have
; in the first two bytes of slot pRAM, so we stick it in here, based on boxFlag. It will be right the
; next time around, but it's not a problem for it to have been zeroed this time, since we will completely
; set it up in this pass of PrimaryInit.
LEA sPRAMBlk(A6),A2 ; point to sPRAM block
MOVE.L A2,spResult(A0) ; point to it
_sReadPRAMRec ; read slot zero's pRAM
TST.W (A2) ; has the board ID been wiped to zero?
BNE.S @BFTest ; if not, then continue
; If pRAM was wiped, then get the correct boardID based on the board sRsrc spID for this boxflag. We'll put
; this in pRAM using an internal slot manager routine (it's in the dispatch table, so we only need to
; know the secret selector).
MOVE.B D1,spID(A0) ; look for the appropriate board sRsrc
_SRsrcInfo ; get the spsPointer to it
MOVE.B #Boardid,spID(A0) ; now get the correct boardID
_sReadWord ;
MOVE.W spResult+2(A0),(A2) ; put this in the boardID position of the pRAM rec
MOVE.L A2,spsPointer(A0) ; point the spBlock at the sPRAM buffer
_InitSlotPRAM ; call the secret selector
@BFTest MOVE.W (A1)+,D2 ; get the loop count
@BFLoop MOVE.B (A1)+,D0 ; get an spID
CMP.B D0,D1 ; is it the one to keep?
BEQ.S @BFLoopEnd ;
MOVE.B D0,spID(A0) ; set up the spBlock for a delete
_sDeleteSRTRec ; delete the non-applicable board sRsrc
@BFLoopEnd DBRA D2,@BFLoop ; for each element
;
; Set up the right CPU sResource. We only recognize 030 and 040 CPUs. All other CPUs are just
; thrown out. Exception: The MacII and MacLC are lumped in with the 030 CPUs for “historical”
; reasons even though they are really 020 CPUs.
;
Move.b BoxFlag,D1 ; Get the BoxFlag for compares.
Lea boxTable030,A1 ; Get pointer to table of 030 boxes.
Move.w (A1)+,D2 ; Set up loop counter
@_030Loop Move.b (A1)+,D0 ; Get a boxFlag.
Cmp.b D0,D1 ; If this is an 030 box,
Beq.s @Nuke040 ; then delete the 040 sRsrc.
Dbra D2,@_030Loop
Lea boxTable040,A1 ; Get pointer to table of 040 boxes.
Move.w (A1)+,D2 ; Set up loop counter.
@_040Loop Move.b (A1)+,D0 ; Get a boxFlag.
Cmp.b D0,D1 ; If this is an 040 box,
Beq.s @Nuke030 ; then delete the 030 sRsrc.
Dbra D2,@_040Loop
Bra.s @NukeAll ; CPU is unrecognized, so go nuke all CPU sRsrcs.
@Nuke040 Move.b #sRsrc_CPUMac040,spID(A0) ; Nuke the sRsrc for 040 CPUs.
_sDeleteSRTRec
Bra.s @EndPruneCPUSRsrcs
@Nuke030 Move.b #sRsrc_CPUMacIIci,spID(A0) ; Nuke the sRsrc for 030 CPUs.
_sDeleteSRTRec
Bra.s @EndPruneCPUSRsrcs
@NukeAll Move.b #sRsrc_CPUMacIIci,spID(A0) ; Nuke the sRsrc for 030 CPUs.
_sDeleteSRTRec
Move.b #sRsrc_CPUMac040,spID(A0) ; Nuke the sRsrc for 040 CPUs.
_sDeleteSRTRec
@EndPruneCPUSRsrcs
;
; Always remove the no-config ROM Double Exposure sRsrc list. If we find that we need it in the V8 PrimaryInit
; code, we will add it back in.
;
MOVE.B #sRsrc_DoubleExposure,spID(A0) ; (it's ID is after all video sRsrc lists)
_sDeleteSRTRec ; delete the Double-x sRsrc list
;
; Do the same for the SONIC Ethernet driver here.
;
TestFor SONICExists ; do we have SONIC hardware? <4>
Bne.s @sonicHalt ; if so, reset the Sonic hardware <T9>
MOVE.B #sRsrc_Sonic,spID(A0) ; no SONIC, so kill the sRsrc list <4>
_sDeleteSRTRec ; delete the SONIC sRsrc list <4>
Bra.s @DoVideo ; now check for video <T9>
;
; Time to reset the Sonic - after all, we don't want it generating interrupts <T9>
; (This was stolen from Sonic.a) <start>
;
WITH SONICRegs
@sonicHalt
MOVE.L A2,-(SP)
MOVE.L UnivInfoPtr,A2 ; get ptr to ProductInfo
ADD.L ProductInfo.DecoderInfoPtr(A2),A2 ; point to the base address table
MOVE.L DecoderInfo.SonicAddr(A2),A2 ; get the Sonic base address in A2
MOVEQ #(1<<RxDisable),D0
MOVE.L D0,Command(A2) ; disable packet reception
@wait
MOVE.L Command(A2),D0
BTST #RxEnable,D0
BNE.S @wait ; wait until it disables
@wait1
;;; MOVE.L Command(A2),D0
;;; EORI.W #(1<<StartTimer)+(1<<RxDisable),D0
;;; BNE.S @wait1 ; make sure no other commands active
;;; BSET #SoftReset,D0
move.l #(1<<SoftReset),D0
MOVE.L D0,Command(A2) ; so we can look at CAM cells
SUB.L D0,D0
MOVE.L D0,Int_Mask(A2) ; disable SONIC interrupts
MOVE.L D0,CAM_Enable(A2) ; wipe out the CAM
MOVEA.L (SP)+,A2 ; <end>
ENDWITH ; <T9>
;
; Originally, the following code was done by using the TestFor macro. However, this became
; impractical for two basic reasons. First, we ran out of feature flags. Second, and
; more importantly, the hardware became both more similar and less similar all at the
; same time. For example, several CPUs started using RBV variants, so the TestFor RBV
; no longer worked at all. In short, for determining uniqueness, TestFor is not very
; useful, whereas boxFlag is.
;
With BivTbl
@DoVideo
Moveq #0,D0 ; Clear this register for word-sized compares.
Move.b BoxFlag,D0 ; Get this machines boxFlag.
Lea BivBoxTbl,A0 ; Point to the table of boxFlags and offsets.
@BoxLoop Cmp.w bivBox(A0),D0 ; If we found a match (or end of list), then
Beq.s @DoInit ; hop to it.
Tst.l (A0)+ ; Otherwise, point to the next entry.
Bne.s @BoxLoop ; Loop if we arent done.
Bra PruneEm ; Otherwise, just get out of here.
@DoInit
Move.w bivOffset(A0),D0 ; Get the offset.
Beq PruneEm ; If its nil, just get out of here.
Jsr BivBoxTbl(D0) ; Otherwise, jump to the code.
Bra AllDone ; And leave. <SM4>
Endwith
; Here is the table of CPUs that are supported by this PrimaryInit and that have built-in video. As can be seen,
; the first item in each entry of this table is a boxFlag (word-sized for alignment), and the second item is
; an offset to the appropriate PrimaryInit code. The BivTbl record (at the top of this file) defines each
; entry.
BivBoxTbl
Dc.w boxMacIIci, RBVInit-BivBoxTbl
Dc.w boxMacIIsi, RBVInit-BivBoxTbl
Dc.w boxMacLC, V8Init-BivBoxTbl
Dc.w boxMacLCII, V8Init-BivBoxTbl ; <SM4>
Dc.w boxQuadra900, DAFBInit-BivBoxTbl ; Original DAFB
Dc.w boxQuadra700, DAFBInit-BivBoxTbl
Dc.w boxQuadra950, DAFBInit-BivBoxTbl
Dc.w boxWombat20, WDAFBInit-BivBoxTbl ; Wombat DAFB
Dc.w boxCentris650, WDAFBInit-BivBoxTbl
Dc.w boxQuadra650, WDAFBInit-BivBoxTbl
Dc.w boxWombat40, WDAFBInit-BivBoxTbl
Dc.w boxQuadra800, WDAFBInit-BivBoxTbl
Dc.w boxWombat40F, WDAFBInit-BivBoxTbl
Dc.w boxCentris610, WDAFBInit-BivBoxTbl
Dc.w boxQuadra610, WDAFBInit-BivBoxTbl
Dc.w boxWLCD33, WDAFBInit-BivBoxTbl
IF forSmurf THEN ; <SM21>
Dc.w boxRiscQuadra700, DAFBInit-BivBoxTbl ; SMURF cards <SM18>
Dc.w boxRiscQuadra900, DAFBInit-BivBoxTbl ; SMURF cards <SM18>
Dc.w boxRiscQuadra950, DAFBInit-BivBoxTbl ; SMURF cards <SM18>
Dc.w boxRiscCentris610, WDAFBInit-BivBoxTbl ; SMURF cards <SM18>
Dc.w boxRiscCentris650, WDAFBInit-BivBoxTbl ; SMURF cards <SM18>
Dc.w boxRiscQuadra800, WDAFBInit-BivBoxTbl ; SMURF cards <SM18>
Dc.w boxRiscQuadra610, WDAFBInit-BivBoxTbl ; SMURF cards <SM20>
Dc.w boxRiscQuadra650, WDAFBInit-BivBoxTbl ; SMURF cards <SM20>
ENDIF
Dc.w boxPowerBook170, JawsInit-BivBoxTbl
Dc.w boxPowerBook140, JawsInit-BivBoxTbl
Dc.w boxClassicII, ApolloInit-BivBoxTbl
Dc.w boxPowerBookDuo210, DBLiteInit-BivBoxTbl
Dc.w boxPowerBookDuo230, DBLiteInit-BivBoxTbl
Dc.w boxPowerBookDuo250, DBLiteInit-BivBoxTbl ; <SM22>
Dc.w boxDBLite20, DBLiteInit-BivBoxTbl ; <SM22>
Dc.w boxPowerBook180, DBLiteInit-BivBoxTbl
Dc.w boxPowerBook160, DBLiteInit-BivBoxTbl
Dc.w boxSTPQ700, DAFBInit-BivBoxTbl ; STP cards <SM23>
Dc.w boxSTPQ900, DAFBInit-BivBoxTbl ; STP cards <SM23>
Dc.w boxSTPQ950, DAFBInit-BivBoxTbl ; STP cards <SM23>
Dc.w boxSTPC610, WDAFBInit-BivBoxTbl ; STP cards <SM23>
Dc.w boxSTPC650, WDAFBInit-BivBoxTbl ; STP cards <SM23>
Dc.w boxSTPQ610, WDAFBInit-BivBoxTbl ; STP cards <SM23>
Dc.w boxSTPQ650, WDAFBInit-BivBoxTbl ; STP cards <SM23>
Dc.w boxSTPQ800, WDAFBInit-BivBoxTbl ; STP cards <SM23>
Dc.w 0,0
;---------------------------------------------------------------
;
; Since this is a Universal ROM, this code takes care of the case
; where there is no internal video. We eliminate all video sRsrc
; lists.
;
;---------------------------------------------------------------
PruneEm
LEA spBlk(A6),A0 ; point A0 at the spBlock
LEA ModeList,A1 ; get the list of video sRsrc spIDs
MOVE.W (A1)+,D1 ; get the count of modes
@0 MOVE.B (A1)+,spID(A0) ; put video spID into spBlock
_sDeleteSRTRec ; remove all entries
DBRA D1,@0
;
; Return to your regularly scheduled start code
;
AllDone
UNLK A6 ; release stack frame
RTS
;---------------------------------------------------------------
;
; This code handles hardware initialization for the RBV Hardware
;
;---------------------------------------------------------------
;
RBVInit
;
; Disable interrupts first
;
MOVE.L RBV,A3 ; point to RBV base
MOVE.B #(1<<BSlot0RBV),RvSEnb(A3) ; set bit 6 (internal video enable) to 0 <1.6>
; in the RBV slot interrupt enable register
;
; test to make sure that we really have RAM in bank A for video
;
MOVEQ #True32B,D0 ; swap to 32 bit address mode <v2.7>
_SwapMMUMode ; now <v2.7>
MOVE.L BootGlobPtr,A0 ;
MOVE.L (A0),D1 ; get address of first BanK
_SwapMMUMode ; switch back to original address mode <v2.7>
TST.L D1 ; see if there is RAM in Bank A <v2.7>
BNE NotFrameBuffer ; kill off the frame buffer
; and video sRsrcs
;
; test if we are a 16MHz CPU and set a flag in the stack frame. This is significant since certain
; video modes are not supported on 16MHz machines.
;
SF.B IsSlowClock(A6) ; assume it's not a slow CPU
CMP.B #boxAuroraCX16,BoxFlag ; is it an 16MHz Aurora?
BEQ.S @Make16 ; yes, so set flag
CMP.B #boxAuroraSE16,BoxFlag ; is it an RBV SE?
BNE.S GetPRAM ; if not, then continue
@Make16 ST.B IsSlowClock(A6) ; set flag
;
; Set up a spBlock then read the currently saved mode out of pRAM. The first
; word is the board ID, followed by the last screen depth's spID. VendorUse2 contains
; the last video sRsrc spID. If no screen is connected, then byte in pRAM doesn't matter,
; but will be set to zero next for next boot. VendorUse3 contains a byte which denotes the
; hw configuration at the last boot. If no screen is connected, this byte isn't critical.
;
GetPRAM
LEA spBlk(A6),A0 ; point to spBlock
LEA sPRAMBlk(A6),A1 ; point to sPRAM block
MOVE.L A1,spResult(A0) ; point to it
_sReadPRAMRec ; read it
MOVE.B 3(A1),D5 ; get the status byte
MOVE.B 4(A1),D6 ; get the config byte
;
; read the current monitor type, and make sure that the sense combination is valid
;
MOVE.B RvMonP(A3),D4 ; get the current monitor information <1.6>
LSR.B #3,D4 ; shift the monitor ID into the low bits
AND.B #7,D4 ; clear out other bits
CMP.B #$0,D4 ; 000 is undefined
BEQ.S noMon ;
CMP.B #$3,D4 ; 011 is undefined
BEQ.S noMon ;
CMP.B #4,D4 ; 100 is undefined
BEQ.S noMon ;
CMP.B #$7,D4 ; if 111 then SE or no connect
BNE.S IsMon ; if not {0,3,4,7}, then it must be a valid combo
@tstSE
CMP.B #boxAuroraSE25,BoxFlag ; is it an RBV SE?
BEQ.S IsMon ; yes, so continue
CMP.B #boxAuroraSE16,BoxFlag ; is it an RBV SE?
BEQ.S IsMon ;
;
; if we have no monitor connected, we get here for a couple of reasons. We definitely want to clear
; D4 to inform the slot manager to remove all video sRsrc lists later. If we didn't have a monitor
; last time, that's all that needs to happen. If there was a monitor last boot, then we need to
; write zero to pRAM for next time.
;
noMon
CLR.B D4 ; clear D4 to zero pRAM next time
CLR.B D6 ; clear config byte too
TST.B D5 ; test the previous pRAM state
BEQ.S FixStack ; if previous was zero, then just continue
BRA.S PutIt ; write zero to pRAM
;
; a reasonable monitor is connected. Has it changed from last time? We need to compare just the
; low 3 bits since the hi-order bits carry family information. The VendorUse3 byte contains
; the previous memory configuration. This is so that we can do the proper invalidations
; if memory changes.
;
IsMon
MOVEQ #0,D0 ; clear D0 out
CMP.L #kMegRAM,MemTop ; greater than 1MB?
BHI.S @1 ; if >, then yes
BSET #3,D0 ; only 1MB, so turn on the 1MB bit
; 16MHz machines (will we ever build any?) don't have all screen depths on Hi-Res and Portrait displays.
; To get their default configuration, set a 16MHz bit
@1
TST.B IsSlowClock(A6) ; is it a 16MHz machine?
BEQ.S @2 ; no, so skip setting bit
BSET #4,D0 ; turn on the 25MHz bit
@2
EXG D0,D6 ; swap real config with pRAM config
EOR.B D6,D0 ; xor them
BNE.S InvalPRAM ; if any bits set, then config changed (D6 has new config)
; compare monitor ids
MOVE.B D5,D0 ; copy the pRAM spID
AND.B #7,D0 ; clear the other bits
CMP.B D0,D4 ; has it changed (no hi-bits in D4 yet)
BNE.S InvalPRAM ; if ≠, then revalidate pRAM
; if we got here, then everything must have been the same
MOVE.B D5,D4 ; if nothing else has changed, then pRAM was OK, so make this the "real"mode
BRA.S FixStack ; everything is OK, so continue
;
; If it is a different type of monitor, then calc the default for this mode, and remember this
; mode in pRAM. The default (D4) is based on CPU speed and memory size. We get this default
; by ORing the monitor type in D4, with the config bits in D6. Remember that these bits are really
; only feature bits when building the default mode. Using Monitors, the user could have overridden
; these choices.
;
InvalPRAM
BSET #7,D4 ; turn on high bit for spID
OR.B D6,D4 ; build the default
CMP.L #kMegRAM,MemTop ; this is a valid size measure at this point in boot
BHI.S InvalScrn ; if >, we don't care about 16MHz-ness
BCLR #4,D4 ; turn off the 16MHz bit
; and inval the scrn resource, too
InvalScrn
CLR.B scrnInval ; just clear this flag byte
;
; if we are changing internal video mode from off or changing screens, let's make the RBV video the
; default screen. The RBV is smart enough to know that a real display is connected, and at this
; point the scrn resource is blown away anyway, so we do this to make the system a little easier to
; test. Hey, this is ROM, so we DESERVE most favored nation status!
;
LEA VidDefBlk(A6),A0 ; point to the block we set up before
_SetVideoDefault ; write it
LEA spBlk(A6),A0 ; point to the spBlock again
; write the new valid sRsrc id (or zero if no video) into pRAM for next time
PutIt
MOVE.B D4,sPRAMBlk+3(A6) ; put new mode in pBlock
MOVE.B D6,sPRAMBlk+4(A6) ; remember the hardware config, too
MOVE.B #firstVidMode,sPRAMBlk+2(A6) ; set the default screen depth
MOVE.L spResult(A0),spsPointer(A0) ; set up parameter block
_SPutPRAMRec ; write the new record out
FixStack ; this name used to mean something, but doesn't now!
;
; set the screen depth to 1-bit/pixel if active, turn video off if not
;
TST.B D4 ; test deactive flag
BNE.S PickOneBit ;
MOVE.B #$40,RvMonP(A3) ; deactivate video <1.6>
BRA.S PruneRBV ; go to sRsrc pruning code
PickOneBit
CLR.B RvMonP(A3) ; set normal video, 1 bit/pixel <1.6>
;
; prune out the invalid sRsrc lists here. Deactivate any spIDs that are the same monitor, but
; different option bits. This code didn't develop that powerful spaghetti flavor until all the
; special cases arose.
;
PruneRBV
LEA spBlk(A6),A0 ; point to the spBlock again
LEA ModeList,A1 ; point at video modes
BSET #7,D4 ; turn on high bit for spID
; This turns illegal ID=0 into $80, which
; is NEVER present in the video sRsrc lists
MOVE.B D4,D3 ; copy the current spID
AND.B #$67,D3 ; reduce to monitor/machine ID
MOVE.W (A1)+,D1 ; get zero-based counter in D1
@0 MOVE.B (A1)+,D2 ; get mode
MOVE.B D2,spID(A0) ; set the mode
; if the mode matches, don't modify it's state
CMP.B D4,D2 ; is this the valid mode?
BEQ.S @10 ; yup, so skip deletion
; unconditionally kill the modes that don't work in 16MHz mode
TST.B IsSlowClock(A6) ; is it a 16MHz RBV machine?
BEQ.S @2 ; if flag clear, then no conditional kill
CMP.W #sRsrc_VidRbvHRa,D2 ; no eight-bit 640*480 in 16MHz machines
BEQ.S @5 ; delete it
CMP.W #sRsrc_VidRbvFPa,D2 ; no four-bit 640*870 in 16MHz machines
BEQ.S @5 ; delete it
@2 MOVE.B D2,D5 ; copy the test mode
AND.B #$67,D5 ; reduce to monitor/machine ID
CMP.B D5,D3 ; is this the correct monitor, but wrong option?
BNE.S @5 ; nope, so kill this spID
MOVE.L #1,spParamData(A0) ; setup to disable this mode
CLR.L spsPointer(A0) ; not a RAM sRsrc
_SetsRsrcState ; set it
BRA.S @10 ; and continue
; remove it
@5 _sDeleteSRTRec ; remove the invalid entry
@10 DBRA D1,@0
;
; if there was no valid video mode, then all video modes have been removed. Get out without
; clearing the screen or setting the CLUT hardware. We still return a good seResult, but
; there will be no video sRsrcs installed so the driver won't be opened.
;
CMP.B #$80,D4 ; was there a valid mode (has high bit on)?
BEQ.S RBVExit ; if clear, there wasn't so flush it
;
; Let's gray the screen now while we still remember the monitor mode in D4
;
GrayNow
AND.B #$7,D4 ; get back to the basic monitor ID
CMP.B #HRId,D4 ; is it Mac II display?
BNE.S @0 ;
LEA pHRParms,A1 ;
BRA.S @10 ;
@0 CMP.B #GSId,D4 ; is it mod'd GS display
BNE.S @1 ;
LEA pGSParms,A1 ;
BRA.S @10 ;
@1 CMP.B #SEId,D4 ; is it an SE display?
BNE.S @2 ; nope
LEA pSEParms,A1 ; must be an SE display
BRA.S @10 ;
@2 LEA pFPParms,A1 ; must be a full page (color or mono)
@10 JSR Blast ; gray the screen
;
; Set up the color table. If it's a monochrome portrait display, then only write to the
; blue channel.
;
InitCLUT
TestFor VDACExists ; see if a VDAC chip is present
BEQ.S RBVExit ; if not, then skip this section
WITH ProductInfo,DecoderInfo
MOVE.L UnivInfoPtr,A0 ; get the pointer to the universal info
ADDA.L DecoderInfoPtr(A0),A0 ; point to the base address table
MOVE.L VDACAddr(A0),A3 ; get the address of the VDAC
ENDWITH
MOVE.B #$FF,vDACPixRdMask(A3) ; set the vDAC mask
LEA vDACwDataReg(A3),A0 ; point to vDAC data write register
MOVE.B #$FE,vDACwAddReg-vDACwDataReg(A0) ; start at position 254
CMP.B #1,D4 ; is it a mono portrait
BNE.S @RGB ; nope, so set all channels
@mono
SF.B (A0) ; white.red is off
SF.B (A0) ; white.green is off
ST.B (A0) ; white.blue
BRA.S RBVExit ; and we're out of here
@RGB
ST.B (A0) ; white.red
ST.B (A0) ; white.green
ST.B (A0) ; white.blue
SF.B (A0) ; black.red
SF.B (A0) ; black.green
SF.B (A0) ; black.blue
BRA.S RBVExit ; <12>
;
; if there was no RAM for video in Bank A, then deactivate the video refreshes, and
; fall through to remove all video sRsrcs
;
NotFrameBuffer
MOVE.B #$40,RvMonP(A3) ; deactivate video and fall thru <1.6>
;
; all done
;
RBVExit
Rts
;
; Here's the PrimaryInit for the V8 hardware. It does a RAM test to see if there is 512K, 256K or
; no video RAM and selects the appropriate video sRsrc. There's also the standard PrimaryInit stuff
; happening here - clearing the screen, setting the CLUT, etc. The family mode implementation is
; pretty straightforward here with the only the Apple // emulation mode on the Rubik.
;
; first, disable interrupts
V8Init
MOVE.L V8,A3 ; get the base address of the V8 chip
MOVE.B #(1<<V8IntIRQEn),V8SEnb(A3) ; disable built-in video and slot interrupts
;
; Read the pRAM record. The slot pRAM is structured like that of the RBV init above.
; As with all slot devices, the first two bytes are the card's board ID, and the
; following byte (VendorUse1) holds the spID of the screen depth. This primaryInit
; keeps the video sRsrc spID in VendorUse2, and the previously booted monitor code in
; VendorUse3.
;
With SP_Params
LEA spBlk(A6),A0 ; point to spBlock
LEA sPRAMBlk(A6),A1 ; point to sPRAM block
MOVE.L A1,spResult(A0) ; point to it
_sReadPRAMRec ; read it
MOVE.B SP_LastConfig(A1),D5 ; get the sRsrc ID byte
MOVE.B SP_DfltConfig(A1),D6 ; get the config byte
Endwith
;
; Read the current monitor type into D3.
;
MOVE.B V8MonP(A3),D3 ; get the current monitor information
LSR.B #3,D3 ; shift the monitor ID into the low bits
AND.B #7,D3 ; clear out other bits
;
; Size the amount of VRAM available in the system. We do this by writing a test pattern
; to the outer bound of each of the VRAM banks, reading the 512K boundary and testing the result.
;
MOVE.L #V8vRAMBase,A2 ; point at the base of VRAM, if present
MOVE.B D3,D4 ; copy monitor code into D4 (which implies 512K)
; Test for 512K vRAM SIMM.
MOVE.L #'512K',(k512KvRAM-4,A2) ; write the test pattern out in the last long
Nop
; Test for 256K vRAM SIMM.
MOVE.L #'256K',(k256KvRAM-4,A2) ; write the test pattern out in the last long
Nop
; Read it back
CMP.L #'512K',(k512KvRAM-4,A2) ; if it matches, then 512K (no change to ID)
BEQ.S @EndSize ;
CMP.L #'256K',(k256KvRAM-4,A2) ; if it matches, then 256K
BNE @NoMon ; if not, then there's no vRAM at all
BSET #3,D4 ; turn on the 256K bit
@EndSize
;
; Set up the video family disabling flag in D7. Look for a Double Exposure card. We shouldn't allow 560*384
; modes if there's no pixel clock. Look for a config ROM first. If there isn't one, then look to see if
; anything is in the slot. If there doesn't seem to be anything there, then do the (dirty) ID sequence. Finally,
; if the connected display is not a Rubik, don't turn on the flag (but go ahead and add the Double Exposure
; sRsrc).
;
SF D7 ; clear D7 for no Double Exposure
LEA spBlk(A6),A0 ; point to spBlock
MOVE.B #3,spTBMask(A0) ; ignore software and hardware IDs <5>
MOVE.W #catCPU,spCategory(A0) ; look for Double Exposure devices <5>
MOVE.W #TypAppleII,spCType(A0) ; <5>
_sNextTypesRsrc ; look for it
BEQ.S @GetFlags ; if no error (sRsrc found), then continue looking at sRsrc
CLR.B spTBMask(A0) ; look for a board sRsrc in slot $E (the expansion slot)
MOVE.W #catBoard,spCategory(A0) ; look for a board type descriptor <5>
MOVE.W #typBoard,spCType(A0) ; <5>
CLR.W spDrvrSW(A0) ; <5>
CLR.W spDrvrHW(A0) ; <5>
MOVE.B #$E,spSlot(A0) ; look in slot $E
MOVEQ #0,D0 ; clear flags for spParamData
BSET #foneslot,D0 ; look only in slot $E
MOVE.L D0,spParamData(A0) ;
_GetsRsrc ; use the new get call
BEQ.S @EndID ; if anything is there, get out with no Double Exposure
BSR DEIDSequence ; call the ID sequence
BNE.S @EndID ; if <>, then no Double Exposure
MOVE.B #sRsrc_DoubleExposure,spID(A0) ; add the Double Exposure ID back in
CLR.B spSlot(A0) ; add it from slot 0 sRsrc directory
CLR.L spsPointer(A0) ; it's in the sRsrc directory
CLR.W spRefNum(A0) ; no driver
CLR.L spParamData(A0) ; add it in active
_InsertSRTRec ;
BRA.S @hasDE ;
@GetFlags MOVE.B #CPU_FlagsID,spID(A0) ; get the flags word
_sReadWord ; read it
BNE.S @EndID ; if not found, then no pixel clock
MOVE.W spResult+2(A0),D0 ; get result flags <7>
BTST #hasPixelClock,D0 ; did it have a clock
BEQ.S @EndID ; set D7 for card present
@hasDE
CMP.B #2,D3 ; is the connected monitor a Rubik?
BNE.S @EndID ; don't allow video families if not
ST D7 ; set flag true for Double Exposure and enable video families
@EndID
CLR.L spParamData(A0) ; reset spParamData to cleared state
CLR.B spSlot(A0) ; reset default operations on slot 0
;
; is there nothing connected?
;
CMP.B #7,D3 ; if bits = 111, then no connect
BNE.S @ChkMon ; if no connect, then blast pRAM
;
; Here's a feature for the manufacturing guys. They would like to boot without a display, then <6><daf,jj>
; plug one in down the line. Normally, this doesn't work since the QD stuff is not set up
; as a consequence of removing all sRsrc lists. To accommodate these guys, we read a
; sequence of locations from pRAM that are initialized to a particular value during
; factory burnin. If we see this signature, and there's no monitor connected, then
; setup for Rubik. The factory guarantees that this setup signature won't be seen outside
; of the factory. Even if it is, it will be OK, since there's no monitor connected,
; and on vRAM machines (all Rubik modes require vRAM), there's no negative effect to the system.
;
MOVE.L A0,-(SP) ; save A0
SUBQ #4,SP ; make four byte buffer
MOVE.L SP,A0 ; point to it
MOVE.L #$000400FC,D0 ; read 4 bytes starting at $FC
_ReadXPRAM ; read it
MOVE.L (SP)+,D0 ; get the result, release buffer
MOVE.L (SP)+,A0 ; restore A0
CMP.L #'RNIN',D0 ; is it the signature?
BNE.S @NoMon ; nope, so set up as if no monitor is connected
;
; Set up registers to look like Rubik setup with appropriate amounts of vRAM. Note D4 has the
; vRAM size flag appropriately set (if there's no vRAM and a hi-res is NOT connected, then
; the code above skips to @NoMon below, and this stuff doesn't happen).
;
MOVE.B #2,D3 ; set to Rubik monitor code
AND.B #$F8,D4 ; clear monitor bits in D4 (which is mon+RAM size)
OR.B D3,D4 ; set to Rubik+vRAM size
MOVE.B D4,D6 ; copy D4 to D6 (last config, but it's not used anymore)
MOVE.B D4,D5 ; make spID for this Rubik/vRAM configuration
OR.B #$A0,D5 ; turn on function spID and Elsie config bits
SF D7 ; no way to get to Double Exposure mode
BRA.S IsSame ; skip ahead without verification checks
@NoMon
CLR.B D4 ; make the monitor type 0 for no video
CLR.B D6 ; clear out the previous config ID, too
BRA.S @WrPRAM ; update the pRAM
;
; Have we changed monitors since last time? If so, we need to invalidate the slot pRAM and
; the scrn resource.
;
@ChkMon
MOVE.B D5,D0 ; copy the saved spID
AND.B #$07,D0 ; clear all but monitor bits
CMP.B #2,D0 ; if =2, then Rubik
BNE.S @0
BTST #4,D5 ; is it an Apple // emulation mode?
BEQ.S @0 ;
TST.B D7 ; if no Double Exposure, then invalidate it
BEQ.S @1 ; treat as changed monitor
@0
CMP.B D6,D4 ; compare to last booted
BEQ.S IsSame ; if unchanged, then continue
@1
MOVE.B D4,D6 ; since it changed, update the register
;
; If the monitor has changed, then we need to make a new default selection. This is simple for
; VISA- we need only OR the configuration with $A0 to get the proper default for each display.
; If there is no video connected we remember it as $A0, which will be an illegal sRsrc ID.
; A1 still has a pointer to the slot pRAM block in the stack frame, and A0 points to the
; slot parameter block.
;
@WrPRAM
MOVE.B D6,4(A1) ; put new configuration in pRAM for next time
MOVE.B D4,D5 ; copy the configuration to sRsrc ID reg
OR.B #$A0,D5 ; turn on the Elsie video sRsrc family bits
MOVE.B D5,3(A1) ; put in pRAM rec as new video sRsrc spID
MOVE.B #$80,2(A1) ; select the first video mode as default
MOVE.L A1,spsPointer(A0) ; reset parameter to this call
_SPutPRAMRec ; write the new record out
;
; Set video to one bit/pixel for PrimaryInit. This is what you do if there is no video as well,
; although the MemTop/MMU code will calculate something different here.
;
IsSame
MOVE.B V8Exp(A3),D0 ; pick up the current expansion register value
MOVE.B D5,D2 ; copy the spID
AND.B #$17,D2 ; extract the monitor bits and bit #4 (on for A// mode)
CMP.B #$12,D2 ; if display = 010 and bit #4, then A// mode
BNE.S @reg ;
BSET #V8A2Mode,D0 ; turn on Apple // screen size
@reg
MOVE.B D0,VsExp(A3) ; set it
; normally, we would just be able to clear the monitor parameters register to set one bit mode, but
; there's a V8 bug with A// mode that requires it to be set to “two” bit mode to display correctly.
CMP.B #$12,D2 ; we built D2 above (this could be better)
BNE.S @notA2 ;
MOVE.B #1,VsMonP(A3) ; pick one bit A// mode
BRA.S PruneElsie ;
@notA2
CLR.B VsMonP(A3) ; pick one bit mode
; remove all non-applicable video sRsrc lists. A0 still points to the spBlock.
PruneElsie
LEA ModeList,A1 ; point at video modes
MOVE.B D5,D4 ; copy the current spID
AND.B #$6F,D4 ; collect Elsie+VRAMSize+monitor bits
MOVE.W (A1)+,D1 ; get zero-based counter in D1
@0 MOVE.B (A1)+,D2 ; get mode
MOVE.B D2,spID(A0) ; set the mode
; if the mode matches, don't modify its state
CMP.B D5,D2 ; is this the valid mode?
BEQ.S @10 ; yup, so skip deletion
@2
MOVE.B D2,D6 ; copy the test mode
AND.B #$6F,D6 ; collect Elsie+VRAMSize+monitor bits for family
CMP.B D6,D4 ; is this the correct monitor, but wrong option?
BNE.S @5 ; nope, so kill this spID
; D7 is a flag register. It's set if Double Exposure hardware is present. If it's not present, then this
; register is clear. The Apple // emulation mode is the only possible family video mode that can be
; present, so if the display is a Rubik, then allow the family mode stuff to take place based on D7 (this
; means either allow the 512*384 mode to be disable if 560*384 was in pRAM, or vice versa). If no
; Double Exposure hardware is present, then the detection code above invalidated the 560 mode selection
; from pRAM, so 512 mode will be selected and 560 mode will not be available. Finally, the 512K vRAM
; and 0K vRAM spIDs look like a family. If the display is not a Rubik, then we won't do 560 mode, so
; there's additional code above that will always clear D7 when a non-Rubik display is present. This
; takes care of this hi-res special case.
TST.B D7 ; should we allow families?
BEQ.S @5 ; no, so always remove
MOVE.L #1,spParamData(A0) ; else, setup to disable this mode
CLR.L spsPointer(A0) ; not a RAM sRsrc
_SetsRsrcState ; set it
BRA.S @10 ; and continue
; remove it
@5 _sDeleteSRTRec ; remove the invalid entry
@10 DBRA D1,@0
;
; don't clear the screen if no video is active. We had to go through the pruning step to
; eliminate video sRsrcs.
;
CMP.B #sRsrc_NeverMatch,D5 ; test for the inactive Elsie sRsrc <4>
BEQ.S V8Exit ; and exit
;
; gray the screen
;
V8ScreenGray
MOVE.B D5,D0 ; copy the sRsrc ID
AND.B #$1F,D0 ; collect monitor+option bits
CMP.B #$3,D3 ; is it a VGA?
BNE.S @0 ; nope, so continue
LEA pVGAParms,A1 ;
BRA.S Cont ;
@0
CMP.B #$16,D0 ; is it the non-vRAM hi-res mode?
BNE.S @1 ;
LEA pHRParms,A1 ; load the parms for the dRAM mode
BRA.S Cont ;
@1
CMP.B #$6,D3 ; is it a hi-res display?
BNE.S @2 ; nope, so continue
LEA pV8HRParms,A1 ; load the parms for the vRAM modes
BRA.S Cont ;
; all that's left are Rubik modes. Rowbytes are the same for the 512*384 and 560*384 mode, so
; we clear both displays for the larger size.
@2 LEA pV8A2Parms,A1 ;
Cont
BTST #3,D5 ; if 256K vRAM then adjust table data upward
ParmShortShift EQU 18 ; !!! ••• !!!
BEQ.S @3 ; if not set, then leave the setup
ADDA #ParmShortShift,A1 ; point at 256K parameters
@3
JSR Blast ; gray the screen
;
; set up the CLUT
;
WITH ProductInfo,DecoderInfo
MOVE.L UnivInfoPtr,A0 ; get the pointer to the universal info
ADDA.L DecoderInfoPtr(A0),A0 ; point to the base address table
MOVE.L VDACAddr(A0),A3 ; get the address of the VDAC
ENDWITH
MOVE.B #$08,V8DACwCntlReg(A3) ; set the DAC to 1bpp, master mode, no overlay
ADDA #V8DACwDataReg,A3 ; point to data reg
MOVE.B #$7F,V8DACwAddReg-V8DACwDataReg(A3) ;
ST.B (A3) ; white.red
ST.B (A3) ; white.green
ST.B (A3) ; white.blue
MOVE.B #$FF,V8DACwAddReg-V8DACwDataReg(A3) ;
SF.B (A3) ; black.red
SF.B (A3) ; black.green
SF.B (A3) ; black.blue
;
; all done
;
V8Exit
Rts
;
; Here's the hardware ID sequence for the original Double Exposure card. The designer was too lame to
; include a configuration ROM to identify the presence of the card in the normal manner, so we include
; a copy of the Double Exposure functional sRsrc list. Thanks to David Wong for the first version of
; this code (in the generalist lower-case style).
;
DEIDSequence
MOVEM.L A2-A5/D0-D2,-(SP) ; save registers in use
; Install our own bus exception handler and switch to 32 bit mode
moveq #True32B,d0
_SwapMMUMode ; change to 32 bit mode
move.w d0,-(sp) ; save old mmu mode
move.w sr,-(sp) ; save current interrupt level.
ori.w #$0700,sr ; disable interrupts
move.l BusErrVct,a4 ; a4 = old exception vector
lea @Uninstall,a2 ; a2 = addr to return to in case of bus exception
lea myBusExcptn,a5 ; addr of our exception handler
move.l a5,BusErrVct ; install our exception handler
; get the card base address. It can only be in one place.
MOVE.L #$FE000000,A3 ; slot E in 32-bit space
; clear D1 and D2 to make sure accidental matches don't happen
CLR.L D1 ; zero them
CLR.L D2
;
; Test for presence of card by reading an address register on the double exposure
; card. If there is no card, we will get a bus error. If there is a card, try
; reading the data register, which is auto-incrementing in value. We recognize the
; presence of the card by it's behavior. Read it once to see if this address range
; bus errors. If it does, then uninstall the exception handler leaving D1 and D2 equal. The
; exit code adds an increment factor to D1, that will only allow them to match if the
; auto-incrementing hardware is present. If this range doesn't bus error, then we read
; the data register 3 times which should cause the address register to increment by three.
; Once again, we hit the exit code which adds 3 to D1 (the value read from the address register).
; If they match, then the card must be present. If they don't then we have some sort of
; hardware here, but it's not a certified Double Exposure.
;
; The address register is read- and write-able, but we are trying to avoid writes to the
; card space since it could be a card with no config ROM (i.e., a bad dog) and we wouldn't
; want to write to it. The register is 16-bits in size, so we control the possibility of
; it wrapping around as we increment by being careful to do word compares and word arithmetic
; (basically, we make the arithmetic look like the way the hardware works).
;
move.w A2eAdrsReg(a3),d1 ; if we bus error then no card
move.w A2eDataReg(a3),d0 ; reading data auto-inc addr reg
addq.w #1,d1
cmp.w A2eAdrsReg(a3),d1 ; did addr reg increment ?
bne.s @Uninstall ; no - card is not present
move.w A2eDataReg(a3),d0 ; try incrementing a few times
move.w A2eDataReg(a3),d0
move.w A2eDataReg(a3),d0
move.w A2eAdrsReg(a3),d2 ; get addr reg value
; Uninstall our bus exception handler
@Uninstall
move.w (sp)+,sr ; restore interrupt level
move.l a4,BusErrVct ; re-install original exception vector
move.w (sp)+,d0
_SwapMMUMode ; restore original mmu mode
addq.w #3,d1
cmp.w d1,d2 ; did addr reg auto inc? Set EQ or NE.
MOVEM.L (SP)+,A2-A5/D0-D2 ; restore registers
RTS
;________________________________________________________________________________________________
;
; Bus exception handler
;
; This is the ID code's replacement bus error exception handler. It is designed
; to detect faulted Nubus address data read bus cycles. It is NOT designed to handle
; data write or read-modify-write cycles, or instruction fetch faults. These exceptions
; are transfered to the old bus exception handler.
;
; Upon an exception, the stack frame type is verified for as being one this routine is
; able to handle (in this case, a long bus cycle stack frame only). The SSW is check
; for a data read cycle fault ONLY. If the fault address is a NuBus address (32 bit
; address), then the exception stack frame is pop-ed and the exception return address
; in reg a2 is jumped to.
;
; Input : reg a2 = addr to set return pc in case of valid bus exception
; a4 = addr of original bus exception vector
;
DEstackframe RECORD 0
savereg DS.L 1 ; saved register on stack
statusreg DS.W 1
programCnt DS.L 1
type DS.B 1 ; format frame type
fill DS.B 3 ; filler
ssw DS.W 1 ; special status register
fill2 DS.L 1 ; filler
DFAddr DS.L 1 ; data cycle fault address
remainder DS.B 72-8 ; remainder of stack frame minus the short frame
shortSR ds.w 1 ; beginning of short stack frame definition
shortPC ds.l 1 ; new pc for short frame
shortvers ds.w 1 ; version and vector offset
ENDR
with DEstackframe
myBusExcptn
; Verify that this is a faulted NuBus read data cycle
move.l d0,-(sp) ; save working register
move.w ssw(sp),d0 ; get special status register
and.w #$F1C0,d0 ; mask FC FB RC RB DF RM RW
cmp.w #$0140,d0 ; DF and RW bit set only ?
bne.s @RealBusEx ; can't handle this case - pass it on
move.b type(sp),d0 ; get format of stack frame for long frame
lsr.b #4,d0 ; look at high nibble
cmp.b #$0B,d0 ; long bus exception frame ?
bne.s @RealBusEx ; transfer to real bus exception handler
move.b DFAddr(sp),d0 ; get high byte of data fault cycle address
cmp.b #$FF,d0 ; in minor slot space range ?
beq.s @RealBusEx ; not in minor slot space
cmp.b #$F0,d0 ; in minor slot space range ?
beq.s @RealBusEx ; not in minor space $F1 - $FE
; Have verified that a NuBus read data access caused the bus error. Need to modify the
; stack frame to return to the address in register a2. Accomplish this by creating a new
; short stack frame and setting a new PC. The long bus exception PC is popped off leaving
; a short exception frame. Cannot just modify the PC in the long frame to return to a new
; address (this doesn't work).
move.l (sp),d0 ; restore reg d0
move.l a2,shortPC(sp) ; set new return address in short frame
move.w statusreg(sp),shortSR(sp) ; move the SR
clr.w shortvers(sp) ; clear frame type and vector offset
adda.w #shortSR,sp ; pop long frame leaving a short frame
rte
; The bus exception was not caused by a read to NuBus - pass the exception to the
; real bus exception handler.
@RealBusEx move.l (sp)+,d0 ; restore reg D0
jmp (a4) ; jump to original bus exception vector
ENDWITH
;••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
;
; Here's the code that initializes the video chip on the TIM system
;
JawsInit
; Remove all non-applicable video sRsrc lists.
;
LEA spBlk(A6),A0 ; point back at spBlock
LEA ModeList,A1 ; point at video modes
MOVE.W (A1)+,D1 ; get zero-based counter in D1
@0 MOVE.B (A1)+,D2 ; get mode
CMP.B #sRsrc_Vid_Tim_LCD,D2 ; is it Tim?
BEQ.S @10 ; if it is, then don't delete
MOVE.B D2,spID(A0) ; set the mode
_sDeleteSRTRec ; remove the all modes
@10 DBRA D1,@0
; gray the screen
LEA pLCDParms,A1 ; point to screen graying parameters
JSR Blast ; gray the screen
; all done (it's so simple...)
Rts
;••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
;
; Heres the code that initializes video for Apollo systems. It looks a heckuvalot like the JawsInit
; code.
;
ApolloInit
; Remove all non-applicable video sRsrc lists.
;
MOVE.L VISA,A0 ; Point to the VISA base.
MOVE.B #$40,RvSEnb(A0) ; Set slot 0 interrupt disabled (slot 0 bit+set/clear to 0).
Lea spBlk(A6),A0 ; Point at spBlock
Lea ModeList,A1 ; Point at the list of video sRsrc modeIDs
Move.w (A1)+,D1 ; Get zero-based counter in D1
@Repeat Move.b (A1)+,D2 ; Get modeID
Cmp.b #sRsrc_Vid_Apollo,D2 ; Is it an Apollo?
Beq.s @Until ; If it is, then dont delete it.
Move.b D2,spID(A0) ; Otherwise, delete it.
_sDeleteSRTRec ;
@Until Dbra D1,@Repeat
; Gray the screen.
;
Lea pApolloParms,A1 ; Point to the screen graying parameters, and
Jsr Blast ; gray the screen.
; And exit.
;
Rts
;••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
;
; Heres the code that initializes video for systems that use the Chips & Technologies 65210 GSC LCD controller.
;
Unimplemented EQU $A89F ; _Unimplemented trap <H29>
DBLiteInit MOVE.W #Unimplemented,D0 ; does the _DockingDispatch trap exist?
_GetTrapAddress ,NEWTOOL
MOVEA.L A0,A1
MOVE.W @DockTrap,D0
_GetTrapAddress ,NEWTOOL
CMPA.L A0,A1
BEQ.S @ClamDone ; -> no, continue
SUBQ.W #4,SP ; result
MOVE.L #dockDockingAttr,-(SP) ; docking selector = get docking attributes
CLR.L -(SP) ; params = nil
@DockTrap _DockingDispatch ; call the handler
MOVE.L (SP)+,D0
BTST #dockNoLCDScreen,D0 ; can we use the LCD with the attached bar? <H34>
BEQ.S @ClamLook ; can use LCD, but check clamshell first <H92>
BRA.S @ClamDone ; set the flag to ignore LCD <H92>
;------------------------------------------------------------------------------------------------------ <H92>
; this code checks to see if we're docked, if we have external video, and if the clamshell is closed: |
; in such a case, we want to allow the system to boot on the external monitor but disable the internal v
; monitor and ignore the state of the clamshell switch
WITH PMgrRec, pmCommandRec
@ClamLook SUBQ.W #4,SP ; result
MOVE.L #dockHardwareAttr,-(SP) ; docking selector = get hardware attributes
CLR.L -(SP) ; params = nil
_DockingDispatch ; call the handler
MOVE.L (SP)+,D0
BTST #dockHasVideo,D0 ; do we have external video power?
BEQ.S @EndDockChk ; nope, so skip case to ignore clamshell
CLR.W -(SP)
MOVE.L SP,-(SP) ; pmRBuffer
MOVE.L (SP),-(SP) ; pmSBuffer
CLR.W -(SP) ; pmLength = 0
MOVE.W #readExtSwitches,-(SP) ; pmCommand
MOVEA.L SP,A0 ; point to the parameter block
_PMgrOp ; get the clamshell info
LEA pmRBuffer+4(SP),SP ; toss the parameter block
BTST #clamshell,(SP)+ ; is the clamshell closed?
BEQ.S @EndDockChk ; -> nope, all done
MOVEA.L PMgrBase,A1 ; point to Power Manager variables
BSET #ignoreClamshell,PmgrFlags3(A1) ; ignore clamshell setting
@ClamDone ST disableLCD(A6) ; don't use internal LCD
@EndDockChk
ENDWITH
;------------------------------------------------------------------------------------------------------ <H92>
; Initialize the GSC.
TestFor MSCChipBit ; <H51>
BEQ.S @NoGSCPower ; <H51>
MOVEA.L UnivInfoPtr,A1 ; Point to the ProductInfo record <H51>
ADDA.L ProductInfo.DecoderInfoPtr(A1),A1 ; then to the baseAddr table. <H51>
MOVEA.L DecoderInfo.RBVAddr(A1),A1 ; then to the baseAddr of the MSC <H51>
MOVE.B #(0<<ifIRQ)|(1<<RvIRQ0En),MSCSlotIER(A1) ; disable GSC interrupts <H63>
BSET #MSCLCDReset,MSCClkCntl(A1) ; turn on clocks to the GSC so we can program it<H51>
@NoGSCPower ; <H51>
Movec VBR,A2 ; get pointer to the VBR <H55><H56>
Move.l BusErrVct(A2),-(SP) ; Save current bus error vector <H55><H56>
Lea GSCBusErrHnd,A0 ; Get pointer to the BusError Vect <H55>
Move.l A0,BusErrVct(A2) ; install our busError handler <H55><H56>
Move.l UnivInfoPtr,A0 ; Point to the ProductInfo record.
Adda.l ProductInfo.DecoderInfoPtr(A0),A0 ; Point to the baseAddr table. <H13>
Move.l DecoderInfo.VDACAddr(A0),A0 ; Get the baseAddr of the GSC (“VDAC” for DB-Lite)
Moveq #7,D0 ; mask off the display ID <H31>
And.b GSCPanelID(A0),D0 ; get display id <H58>
Move.l (SP)+,BusErrVct(A2) ; restore BusErrHandler <H55><H56>
Cmp.l #-1,D0 ; IF BusError THEN <H55>
Beq.w PruneEm ; no Internal Video, Exit <H55>
Move.l D0,D2 ; save a copy of display id <H58>
MULU #(GSCPanelSkew-GSCPanelSetup+1)+(GSCDiag2-GSCDiag0+1),D0 ; <H31>
LEA GSCInitTable,A2 ; point to the entry for this display <H31>
ADDA.L D0,A2 ; <H51>
ADDQ.W #GSCPanelSetup,A0 ; point to the first register to blast <H31>
MOVE.L (A2)+,(A0)+ ; initialize the main display registers <H31>
MOVE.L (A2)+,(A0)+ ; <H31>
LEA GSCDiag0-GSCPanelSkew-1(A0),A0 ; point to the diagnostic registers <H31>
MOVE.B (A2)+,(A0)+ ; and initialize them too <H31>
MOVE.W (A2)+,(A0)+ ; <H31>
; Turn GSC and LCD power on/off depending on if we're going to use the LCD screen.
TestFor MSCChipBit ; <H33>
BEQ.S @NotMSC ; <H33>
MOVEQ #screenOn-256,D0 ; assume we want to turn the screen on <H33>
TST.B disableLCD(A6) ; do we? <H33>
BEQ.S @UseLCD ; -> yes <H33>
MOVEQ #screenOff,D0 ; no, we want to turn it off <H33>
BCLR #MSCLCDReset,MSCClkCntl(A1) ; turn off clocks to the GSC <H51>
@UseLCD MOVE.B D0,-(SP) ; put the on/off switch into the buffer <H32>
MOVE.L SP,-(SP) ; pmRBuffer <H32>
MOVE.L (SP),-(SP) ; pmSBuffer <H32>
MOVE.W #1,-(SP) ; pmLength = 1 <H32>
MOVE.W #power1Cntl,-(SP) ; pmCommand <H32>
MOVEA.L SP,A0 ; point to the parameter block <H32>
_PMgrOp ; turn on/off the LCD screen <H32>
LEA pmCommandRec.pmRBuffer+4+2(SP),SP ; toss the parameter block <H32>
@NotMSC ; <H33>
; Set up pRAM.
;
With SP_Params
DBLiteWritePRAM
Move.b #sRsrc_Vid_GSC_LCD,D3 ; use the 640x400 sRsrc for GSC <H21>
Lea spBlk(A6),A0 ; Point to spBlock.
Lea sPRAMBlk(A6),A2 ; Point to sPRAM block.
MOVE.L A2,spResult(A0) ;
_sReadPRAMRec ;
Cmp.b SP_DfltConfig(A2),D3 ; If weve been here before,
Beq.s @EndPRAMSetup ; then just go on.
Move.b D3,SP_DfltConfig(A2) ; Otherwise, remember weve been here.
Lea GSCDefDepthTbl,A1 ; get default depth depending on display type <H59>
Move.b (A1,D2.W),SP_Depth(A2) ; set pram buffer <H59>
Move.l A2,spsPointer(A0) ; Set up parameter block.
_sPutPRAMRec ; Write the new record out
@EndPRAMSetup
Endwith
; Remove all non-applicable video sRsrc lists.
;
DBLitePrune
Lea spBlk(A6),A0 ; Point at spBlock
Lea ModeList,A1 ; Point at the list of video sRsrc modeIDs
Move.w (A1)+,D1 ; Get zero-based counter in D1
@Repeat Move.b (A1)+,D2 ; Get modeID
Move.b D2,spID(A0) ; and save it
Cmp.b D3,D2 ; Is it a DB-Lite?
Beq.s @CheckDisable ; -> yes <H27>
_sDeleteSRTRec ; delete the sRsrc
bra.s @Until ; <H27>
@CheckDisable tst.b disableLCD(A6) ; should we disable DBLite sRsrcs? <H27>
beq.s @Until ; -> nope <H27>
MOVE.L #1,spParamData(A0) ; 1=disable <H27>
CLR.L spsPointer(A0) ; not a RAM sRsrc <H27>
_SetsRsrcState ; disable the sRsrc <H27>
@Until Dbra D1,@Repeat
; Gray the screen.
;
tst.b disableLCD(A6) ; are we using the LCD screen? <H27>
bne.s @Done ; -> nope, no point in graying it <H27>
Lea pLCDParms,A1 ; Point to the screen graying parameters, and
Bsr Blast ; gray the screen.
@enablescreen
TestFor NiagraExistsBit ; check for niagra chip <H57>
BEQ.S @unblankGSC ; if not niagra, just unblank the GSC <H57>
MOVE.l #$00EA0E00,-(SP) ; write $0E to addr $00EA <H57>
MOVE.L SP,-(SP) ; pmRBuffer <H57>
MOVE.L (SP),-(SP) ; pmSBuffer <H57>
MOVE.W #3,-(SP) ; pmLength = 3 <H57>
MOVE.W #writePmgrRAM,-(SP) ; pmCommand <H57>
MOVEA.L SP,A0 ; point to the parameter block <H57>
_PMgrOp ; unblank the display <H57>
LEA pmCommandRec.pmRBuffer+4+4(SP),SP ; toss the parameter block <H57>
@unblankGSC
Move.l UnivInfoPtr,A0 ; Point to the ProductInfo record.
Adda.l ProductInfo.DecoderInfoPtr(A0),A0 ; Point to the baseAddr table. <H57>
Move.l DecoderInfo.VDACAddr(A0),A0 ; Get the baseAddr of the GSC (“VDAC” for DB-Lite)<H57>
bset.b #GSCBlankCtl,GSCGrayScale(A0) ; gsc enable <H57>
; And exit.
;
@Done Rts
; GSC initialization table. Each entry is based on the LCD panel ID. <H31>
;
; panel gray poly panel ACD refresh blank panel
; setup scale adjust adjust clock rate shade skew diag0 diag1 diag2
GSCInitTable DC.B $10, $00, $64, $80, $80, $02, $05, $A0, $00, $00, $03 ; ID=0 TFT1Bit
DC.B $12, $00, $64, $00, $80, $02, $05, $F0, $00, $00, $0B ; ID=1 TFT3Bit <H88>
DC.B $10, $00, $64, $80, $80, $02, $05, $FF, $00, $00, $03 ; ID=2 TFT4Bit <H50>
DC.B $10, $00, $64, $80, $80, $02, $05, $A0, $00, $00, $03 ; ID=3 NotAssignedTFT
DC.B $10, $00, $64, $80, $80, $05, $05, $A0, $00, $00, $03 ; ID=4 NotAssignedSTN <H50>
DC.B $10, $00, $63, $80, $80, $05, $05, $A1, $00, $00, $03 ; ID=5 TimSTN <H50>
DC.B $10, $00, $63, $00, $80, $05, $05, $9C, $00, $00, $03 ; ID=6 DBLiteSTN <H63>
DC.B $10, $00, $64, $80, $80, $05, $05, $A0, $00, $00, $03 ; ID=7 No Display <H50>
; GSC default bit depth table. Each entry is based on the LCD panel ID. <H58>
GSCDefDepthTbl DC.B ThirdVidMode ; ID=0 TFT1Bit
DC.B ThirdVidMode ; ID=1 TFT3Bit
DC.B ThirdVidMode ; ID=2 TFT4Bit
DC.B ThirdVidMode ; ID=3 NotAssignedTFT
DC.B SecondVidMode ; ID=4 NotAssignedSTN
DC.B SecondVidMode ; ID=5 TimSTN
DC.B ThirdVidMode ; ID=6 DBLiteSTN <H66>
DC.B 0 ; ID=7 No Display
;--------------------------------------------------------------------- <H55>
; |
; Routine: GSCBusErrHandler v
;
; Inputs: none
;
; Outputs: none
;
; Destroys: none
;
; Function: bus error handler to detect whether a GSC is present
; on Board. This is important since on Monet, the CPU
; will be identical to Dart with the exception of GSC.
;---------------------------------------------------------------------
GSCstckfrm RECORD 0,Increment
statusreg DS.W 1 ; status register
programCnt DS.L 1 ; program counter
type DS.B 1 ; format frame type
vectOff DS.B 1 ; vector offset
IntReg DS.W 1 ; Internal Register
ssw DS.W 1 ; special status register
InstPipe DS.L 1 ; Instruction Pipe
DFAddr DS.L 1 ; data cycle fault address
IntReg2 DS.L 1 ; more internal registers
DataOBuff DS.L 1 ; data output buffer
IntReg3 DS.L 1 ; more internal registers
ShortBusSz EQU * ; size of short stack frame
IntReg4 DS.L 1 ; more internal registers
StageB DS.L 1 ; stage B address
IntReg5 DS.L 1 ; more internal registers
DataIBuf DS.L 1 ; Date Input Buffer
IntReg6 DS.W 3 ; more internal register
vers DS.B 1 ; version #
IntInfo DS.B 1 ; internal information
IntRegs7 DS.W 18 ; more internal register
LongBusSz EQU * ; size of long stact frame
ENDR
WITH GSCstckfrm
GSCBusErrHnd
move.w ssw(sp),d0 ; get special status register
and.w #%1100111011111111,d0 ; FC FB rc rb X X X df RM RW SIZE X FC2 FC1 FC0
move.w d0,ssw(sp) ; set SSW to not rerun cycle
moveq #-1,d0 ; Indicate a bus error
move.l d0,DataIBuf(sp) ; Must return valid data
rte ; <H55>
ENDWITH
;
; Here's the code that initializes the DAFB system. The other segments above depend on a
; particular construction of the spIDs to identify the properties of each configuration. DAFB
; has too many variants for this mechansism to work well, so this section of code determines
; the connected display and memory configuration and uses that info to select the appropriate spID.
;
WDAFBInit
Move.b #1,wombatDAFB(A6) ; For now, just say were on a Wombat.
Bra.s StartDAFB ;
DAFBInit
Move.b #0,wombatDAFB(A6) ; Say we dont want to do the Wombat-specific code.
; Do this entire thing in 32-bit mode.
;
StartDAFB
MOVEQ #true32b,D0 ; Swap to 32-bit addressing mode.
_SwapMMUMode ;
MOVE.B D0,saveMMUMode(A6) ; Save the old mode.
; Determine the clock speed and save it. The act of reading VIAs can cause pending interrupts
; to be lost, so we want only want to do this once while it doesnt matter (i.e., the Slot
; Manager calls PrimaryInit with interrupts disabled).
;
Tst.b wombatDAFB(A6) ; If we have a Wombat,
Bne.s @WombatSpeed ; then set up for it.
Move.l VIA2,A0 ; Point to VIA2.
Btst #v2Speed,vBufB(A0) ; Test the speed register (25 vs. 33 MHz).
Bra.s @EndDAFBSpeed
@WombatSpeed Move.l VIA,A0 ; Point to VIA1.
Btst #vCpuId2,vBufA(A0) ; Test CPUID reg 2 (20/25 vs 33/40 MHz).
@EndDAFBSpeed Seq IsSlowClock(A6) ; Set the speed flag appropriately.
; Get some useful values up front. Note: On Wombat, the DAFB hardware is NOT tied to the 040
; reset instruction. So, we need to manually reset Wombats DAFB to always put the video
; controller into a known state. To do this, we just need to reset the DAFB and DAFB-Swatch
; registers. The clock chip and the CLUT/DAC are ALWAYS fully reset by the initialization
; code. We go ahead and do this DAFB/DAFB-Swatch reset even in the case of Spike/Eclipse/
; Zydeco because we could be rebooting ala the Cub-card, and a similar reset problem arises
; there.
;
MOVE.L UnivInfoPtr,A4 ; Get ptr to ProductInfo.
MOVE.L A4,A3 ; Copy the ProductInfo ptr.
ADD.L ProductInfo.DecoderInfoPtr(A3),A3 ; Point to the base address table.
MOVE.L DecoderInfo.DAFBAddr(A3),A3 ; Get the DAFB base address in A3.
Move.l A3,A2 ; Copy the DAFB base address.
Lea @DAFBDfltTbl,A1 ; Point to the defaults.
Moveq #DAFB_NumRegs-1,D0 ; Init the loop counter.
@InitDAFBLoop Move.l (A1)+,(A2)+ ; Reset a DAFB register…
Dbra D0,@InitDAFBLoop ; …and loop until done.
Move.l A3,A2 ; Copy the DAFB base address again.
Adda.w #Swatch_BaseOffset,A2 ; Point to the Swatch registers.
Moveq #Swatch_NumRegs-1,D0 ; Init the loop counter.
@InitSwatchLoop Clr.l (A2)+ ; Clear a Swatch register…
Dbra D0,@InitSwatchLoop ; …and loop until done.
Bra.s @EndWombatDAFBInit
@DAFBDfltTbl Dc.l 0,0,0,0,0,0,0,7 ; Default values to program…
Dc.l 7,0,0,0 ; …the DAFB registers with.
@EndWombatDAFBInit
; For Wombat, 40MHz CPUs are possible, and we need to know about them in order to set up the wait-state
; bits in the DAFBConfig register correctly.
;
Tst.b WombatDAFB(A6) ; If were not on a Wombat,
Beq.s @EndDAFBSpeed2 ; then just go on.
Tst.b IsSlowClock(A6) ; If were not running “fast,”
Bne.s @EndDAFBSpeed2 ; then just go on.
Btst #vCpuId1,vBufA(A0) ; Otherwise, test CPUID reg 1 (33 vs. 40 MHz).
Beq.s @EndDAFBSpeed2 ; If not 40MHz, just go on.
Ori.l #(1<<w40MHz),DAFBFlags(A3) ; Otherwise, set the 40MHz-flag bit.
@EndDAFBSpeed2
; Determine if we have the 16bpp-capable ACDC (AC842A) by exploiting some of the new
; features that dont exist in the earlier version of ACDC (AC842). The Nops are
; used because DAFBs address space is non-serial, and we need for the writes to
; happen BEFORE the reads here (see the 040 Programmers Reference for more
; information on this).
;
Clr.l ACDC_AddrReg(A3) ; Tell ACDC to use PCBR0.
Nop
Move.l #$06,ACDC_ConfigReg(A3) ; Put ACDC into indirect mode.
Nop
Move.l #1,ACDC_AddrReg(A3) ; Tell ACDC to use PCBR1.
Nop
Clr.l ACDC_ConfigReg(A3) ; Clear PCBR1.
Nop
Clr.l ACDC_AddrReg(A3) ; Switch back to PCBR0.
Nop
Move.l ACDC_ConfigReg(A3),D0 ; Read PCBR0.
Andi.l #$0F,D0 ; Strip off the junk.
Cmpi.b #$06,D0 ; If ACDC is still in direct mode,
Seq has16bppACDC(A6) ; then an AC842A is present.
Bne.s @EndCLUTChk ; If an AC842A-like DAC isnt present, just go on.
Move.l #1,ACDC_AddrReg(A3) ; Otherwise, tell ACDC to use PCBR1.
Nop ; (Do-Dah)
Move.l ACDC_ConfigReg(A3),D0 ; Read PCBR1.
Andi.l #$0F,D0 ; Strip off the junk.
Beq.s @NoAntelope ; If mfg. and rev. #s are not 0, weve got an Antelope.
Move.b #1,hasLin16bppCLUT(A6) ; Otherwise, weve got one.
Bra.s @EndCLUTChk ;
@NoAntelope Move.b #0,hasLin16bppCLUT(A6) ; No Antelopes here.
@EndCLUTChk
; Do a preliminary DAFB setup so that we can test RAM and read sense lines.
;
Tst.b wombatDAFB(A6) ; If we a have a WombatDAFB,
Bne.s @WombatPrelim ; then set up for it.
LEA DAFBPrelimInit,A1 ; Point to minimal vidparams.
Bra.s @EndDAFBPrelim ;
@WombatPrelim Lea WDAFBPrelimInit,A1 ; Point to WombatDAFB vidParams.
@EndDAFBPrelim
; Do the hardware setup (as they appear in the DAFB parameters).
;
With DAFBVidParams
MOVEQ #0,D0 ; Clear upper part of D0.
MOVE.L A3,A2 ; Copy DAFB base address (for DAFB macros).
Move.l A1,vidParamsPtr(A6) ; Remember which params were using.
; Setup Clock chip.
;
Clr.b clkSetup(A6) ; Say that the clock is not initialized.
Bsr SetupDAFBClk ; Go initialize it.
; Setup DAFB.
;
DAFBSetVidBaseAddr #DAFBStdOffset ; Set up the video base address.
DAFBWWrite dvpRowWords,DAFB_RowWords ; Set up the RowWords.
DAFBWWrite dvpConfig,DAFB_Config ; Set up the controller.
DAFBSpeedPI ; Configure DAFB for right CPU speed.
; Setup Swatch.
;
DAFBWWrite dvpTimingAdj,Swatch_TimeAdj ; Set up timing adjustments.
Move.l #dafbEnableSwatch,Swatch_Mode(A3) ; (We want to reset DAFB “on”, then idle it.)
DAFBWWrite dvpHSerr,Swatch_HSerr ; Set up horizontal timing…
DAFBWWrite dvpHlfLn,Swatch_HlfLn ;
DAFBWWrite dvpHEq,Swatch_HEq ;
DAFBWWrite dvpHSP,Swatch_HSP ;
DAFBWWrite dvpHBWay,Swatch_HBWay ;
DAFBWWrite dvpHBrst,Swatch_HBrst ;
DAFBWWrite dvpHBP,Swatch_HBP ;
DAFBWWrite dvpHAL,Swatch_HAL ;
DAFBWWrite dvpHFP,Swatch_HFP ;
DAFBWWrite dvpHPix,Swatch_HPix ;
DAFBWWrite dvpVHLine,Swatch_VHLine ; Set up vertical timing…
DAFBWWrite dvpVSync,Swatch_VSync ;
DAFBWWrite dvpVBPEq,Swatch_VBPEq ;
DAFBWWrite dvpVBP,Swatch_VBP ;
DAFBWWrite dvpVAL,Swatch_VAL ;
DAFBWWrite dvpVFP,Swatch_VFP ;
DAFBWWrite dvpVFPEq,Swatch_VFPEq ;
Endwith
; Everything's configured, so do the DAFB reset sequence
;
DAFBReset ; Reset DAFB.
; Kill slot interrupts on DAFB.
;
CLR.L Swatch_IntMsk(A3) ; Turn off all interrupts.
; Determine the frame buffer size. For Spike/Eclipse/Zydeco, it is possible to have up
; to 4 (0..3) banks of 512K of vRam. On an Eclipse/Zydeco, there are 2 banks soldered to
; the board itself, while Spikes only have one bank soldered down. Unfortunately,
; the non-soldered down banks (i.e., the SIMM banks) can be non-contiguously arranged.
; That is, 512K of vRam can be plugged into bank 3, while banks 1 and/or 2 are empty.
; In such a case, only 512K of vRam (i.e., bank 0) is useable. Since there is
; always at least 512K of vRam around for Spike/Eclipse/Zydeco, we start looking at
; bank 1 (i.e., the 1 Meg case). For Wombat, only 2 banks of vRAM are possible,
; but we check everything just in case.
;
; Note: The Nops are used after each of the writes because DAFBs address space
; is non-serial.
;
MOVE.L A4,A0 ; Get ptr to ProductInfo.
ADDA.L ProductInfo.VideoInfoPtr(A4),A0 ; Point to the VideoInfo record.
MOVE.L VideoInfo.VRAMLogAddr32(A0),A0 ; Get the frame buffer base address.
Move.l A0,vRAMBaseAddr(A6) ; Save it for later.
Moveq #8-1,D0 ; Just to get the vRAM state machines
@MassageVRAM Tst.l (k2MvRAM-4,A0) ; going, we go out and read VRAM
Tst.l (k1536KvRAM-4,A0) ; a few times. We really only
Tst.l (k1MvRAM-4,A0) ; need to do this for Wombat,
Tst.l (k512KvRAM-4,A0) ; but it doesnt hurt Spike/Eclipse/
Dbra D0,@MassageVRAM ; Zydeco.
MOVE.L #'2MEG',(k2MvRAM-4,A0) ; Write a test value into alleged vRAM.
Nop
Move.l #'1.5M',(k1536KvRAM-4,A0) ; Still another value goes here.
Nop
MOVE.L #'1meg',(k1MvRAM-4,A0) ; Write a different value at this point.
Nop
MOVE.L #'512K',(k512KvRAM-4,A0) ; And, finally, a different value here.
Nop
Moveq #2,D2 ; Assume there is only 512K of vRam.
Cmp.l #'1meg',(k1MvRAM-4,A0) ; If the 1 MB flag didnt stick
Bne.s @EndSize ; then only 512K is possible.
Subq #1,D2 ; Otherwise, theres at least 1MB.
Cmp.l #'1.5M',(k1536KvRAM-4,A0) ; If the 1.5 MB flag didnt stick
Bne.s @EndSize ; then only 1 Meg is possible.
Cmp.l #'2MEG',(k2MvRAM-4,A0) ; If the 2 MB flag didnt stick.
Bne.s @EndSize ; then only 1 MB is possible.
Subq #1,D2 ; Otherwise, 2 MBs exist.
@EndSize Move.l DAFBFlags(A3),D0 ; Get the DAFBFlags.
Bfins D2,D0{vRamBits:numVRamBits} ; Set the amount of vRam.
Tst.b wombatDAFB(A6) ; If were not a Wombat,
Beq.s @ChkCLUTType ; then just go on.
Bset #isWombat,D0 ; Otherwise, say were a Wombat.
@ChkCLUTType Tst.b hasLin16bppCLUT(A6) ; If we dont have an Antelope,
Beq.s @SetDAFBFlags ; then just go on.
Bset #wLin16Bpp,D0 ; Otherwise, say weve got an Antelope.
@SetDAFBFlags Move.l D0,DAFBFlags(A3) ; Write it back out.
DAFBIdle ; Idle DAFB (i.e., turn off vRAM refreshes).
; Read the monitor type into D4.
;
Clr.b sogSwitch(A6) ; Initialize the sync-on-green (safety) switch.
Clr.b altSenseEnb(A6) ; Assume that we were AltSensing last time.
LEA sPRAMBlk(A6),A0 ; Point to the pRAM block on the stack.
Bclr #spAltSenseEnb,SP_Params.SP_Flags(A0) ; Assume that we arent AltSensing this time.
Beq.s @EndAltSenseChk ; We werent
Move.b #1,altSenseEnb(A6) ; We were.
@EndAltSenseChk
Moveq #0,D4 ; Initialize senseline register.
DAFBReadSenseLines D4 ; Read em!
Cmp.b #indexedSense2P,D4 ; If we got a type-3, then do the
Beq.s @Extended2P ; extended Two-Page stuff.
Cmp.b #indexedSenseRGBFP,D4 ; If we got a type-5, then do the
Beq.s @ExtendedRGBFP ; extended RGB Full-Page stuff.
Cmp.b #indexedSenseHR,D4 ; If we got a type-6, then do the
Beq.s @ExtendedHR ; extended Hi-Res stuff.
CMP.B #indexedNoConnect,D4 ; If we got a type-7, then do the
Beq.s @ExtendedNoConnect ; extened no-connect stuff.
Bra @EndSense ; Otherwise, we already recognize the display.
@Extended2P
Bsr DoDAFBExtendedSense ; Do the extended Two-Page algorithm.
Cmp.b #extended2PRdRGB,D4 ; If this is not a Radius Color TPD,
Bne.s @TryRDMono ; then try the Mono TPD.
@SetRDRGB Move.l DAFBFlags(A3),D0 ; Otherwise, get the DAFBFlags.
Bset #RadiusTPDBit,D0 ; Say theres a Radius TPD.
Bset #RadiusDevType,D0 ; Say its color.
Move.l D0,DAFBFlags(A3) ; Write out the flags.
Move.b #indexedSenseRGB2P,D4 ; Say that its a Vesuvio for now.
Bra @EndSense ; And go on.
@TryRDMono Cmp.b #extended2PRdMono,D4 ; If this is not a Radius Mono TPD
Bne.s @End2P ; then just say its a Two-Page.
@SetRDMono Move.l DAFBFlags(A3),D0 ; Otherwise, get the DAFBFlags.
Bset #RadiusTPDBit,D0 ; Say theres a Radius TPD.
Bclr #RadiusDevType,D0 ; Say its monochrome.
Move.l D0,DAFBFlags(A3) ; Write out the flags.
@End2P Move.b #indexedSense2P,D4 ; Say that its a Kong for now.
Bra @EndSense ; And go on.
@ExtendedRGBFP
Bra @EndSense ; Do nothing, as these extended codes arent
; supported yet.
@ExtendedHR
Move.b #extendedHR,D4 ; For now, use any of the type 6 sense codes
Bra @AltSense ; to trigger the alternate senseID scheme.
@ExtendedNoConnect
Bsr DoDAFBExtendedSense ; Do the extended no-connect algorithm.
Cmp.b #extendedNoConnect,D4 ; If there really is nothing connected,
Beq.s @EndNoConnect ; then just go on.
Lea @XNCTable,A1 ; Point to the table of extended no-connect codes.
@XNCLoop Move.b (A1)+,D0 ; Pick up the next supported extended no-connnect code.
Bmi.s @EndNoConnect ; If were at the end of the list, then just leave.
Move.b (A1)+,D1 ; Pick up the indexed version of the extended code.
Cmp.b D0,D4 ; If we didnt find a match, then
Bne.s @XNCLoop ; just keep looping
Move.b D1,D4 ; Translate the extended code into its indexed version.
Bra @EndSense
@XNCTable Dc.b extendedSensePAL,indexedSensePAL
Dc.b extendedSensePALBox,indexedSensePAL
Dc.b extendedSenseNTSC,indexedSenseNTSC
Dc.b extendedSenseVGA,indexedSenseVGA
Dc.b extendedSenseGF,indexedSenseGF
Dc.b extendedSense19,indexedSense19
Dc.b -1,-1
@EndNoConnect Move.b #indexedNoConnect,D4 ; We dont recognize the code, so say nothings connected.
; When no monitor is connected, we first want to check to see if were at the factory
; If we are, then the last 4-bytes of pRAM will contain a special signature. If
; we arent at the factory and we dont recognize the no-connect code, then we
; set up to delete all the video data structures and to turn built-in video off.
;
With SP_Params
@ChkPRAM
Subq #burnInSiz,Sp ; Get pRAM buffer on stack (4-bytes).
Move.l Sp,A0 ; Point to it.
Move.w #burnInSiz,D0 ; Set up parameters
Swap D0 ;
Move.w #burnInLoc,D0 ;
_ReadXPram ;
Move.l (Sp)+,D0 ;
Beq @EndSense ; Just leave if theres no signature.
Lea @NCTable,A1 ; Point to the table of no-connect signatures.
@NCLoop Move.l (A1)+,D1 ; Pick up the next supported code.
Beq @EndSense ; If were at the end of the list, then just leave.
Move.l (A1)+,D3 ; Pick up the indexed version of the no-connect signature.
Cmp.l D0,D1 ; If we didnt find a match, then
Bne.s @NCLoop ; just keep looping.
Move.b D3,D4 ; Translate the no-connect signature into an index.
Bra @EndSense
@NCTable Dc.l burnInSig,indexedSenseHR ; Table of recognized no-connect signatures with…
Dc.l burnInSigAlt,indexedSenseRubik ; …corresponding index.
Dc.l burnInSig12,indexedSenseRubik
Dc.l burnInSig13,indexedSenseHR
Dc.l burnInSig15,indexedSenseRGBFP
Dc.l burnInSig16,indexedSenseGF
Dc.l burnInSig19,indexedSense19
Dc.l burnInSig21,indexedSenseRGB2P
Dc.l 0,0
@AltSense
LEA sPRAMBlk(A6),A2 ; Point to an sPRAM block.
Move.b SP_AltSense(A2),D0 ; Get the alternate senseID pRam byte.
Andi.b #spAltSenseValidMask,D0 ; If it is valid, then just pretend that
Bne.s @DoMonID ; the monID monitor is attached.
Cmp.b #extendedHR,D4 ; Otherwise, if we got here via type-6 sense,
Beq.s @DoHR ; just say an HR is attached.
Bra.s @EndSense ; (Should never get here.)
@DoHR Move.b #indexedSenseHR,D4 ; Say an HR display is attached.
Bra.s @EndSense
@DoMonID Move.b SP_AltSense(A2),D4 ; Get the no-connect pRam byte.
Andi.b #spAltSenseMask,D4 ; Strip the validation code.
Bset #spAltSenseEnb,SP_Flags(A2) ; Say that were AltSensing this time.
Tst.b altSenseEnb(A6) ; If we werent AltSensing last time,
Beq.s @ChkRdTPD ; then just go on.
Move.b #1,sogSwitch(A6) ; Otherwise, remember to leave sync-on-green alone.
@ChkRdTPD Cmp.b #extended2PRdRGB,D4 ; If we got the Radius ColorTPD code,
Beq @SetRDRGB ; then do the Radius kludge.
Cmp.b #extended2PRdMono,D4 ; If we got the Radius MonoTPD code,
Beq @SetRDMono ; then do the other Radius kludge.
@EndSense
Endwith
;
; Figure out what the favored configuration is. After this routine, the favored spID is in D5;
; D7 contains the video mode family alternatives concatenated together (no configuration ever
; has more than four family members). In a little while, we'll have the current selected mode into
; D5 from pRAM. It would be nice to be able to use a RECORD structure here for the DAFBTable entries,
; but it wouldn't allow us to index into the three mode entries, so we just fake it.
;
; D6 maintains the indexed sense id.
;
@GetConfig
LEA DAFBTable,A0 ; Point to DAFB configuration table.
LEA (A0,D4*DT_Size),A0 ; Point to the entry set for this display.
MOVE.L DT_Family(A0),D7 ; Get the family alternatives.
MOVE.B DT_Mode(A0,D2),D5 ; Get the default spID.
Moveq #0,D6 ; Clear for safety.
Move.b D4,D6 ; Save indexed sense ID.
;
; Read the old configuration from slot pRAM to confirm that it's OK.
;
With SP_Params
LEA sPRAMBlk(A6),A2 ; Point to an sPRAM block.
Move.b D6,SP_MonID(A2) ; Set up to save indexed monID into pRAM.
Bclr #spHas16bppACDC,SP_Flags(A2) ; Assume that the AC842A is NOT around.
Bclr #spHas16bppSRsrc,SP_Flags(A2) ; Assume that 16bpp-capable sRsrc will NOT be loaded.
Bset #spPageMode,SP_Flags(A2) ; Setup to turn pagemode on when optimal.
;
; If we have the new ACDC (i.e., AC842A), then we can do 16bpp if we arent blocking it. We block the use
; of 16bpp when 1) The machine doesnt have the 16bpp ACDC, 2) we arent running at 33 Mhz, 3) DAFB is
; not the right revision number or better, and/or 4) there is not enough VRam to support 16bpp in the
; current configuration.
;
Tst.b has16bppACDC(A6) ; If we dont have the AC842A,
Beq.s @CheckConfig ; then just continue with the config check.
Bset #spHas16bppACDC,SP_Flags(A2) ; Set up to write out that the AC842A is around.
Cmp.b #sRsrc_Vid_DAFB_GSa,D5 ; If we only have 512K of VRam and a Rubik is attached,
Beq.s @Do16bpp ; then do the 16bpp stuff anyway.
Cmp.b #2,D2 ; Otherwise, if D2 = 2, we only have 512K of VRam,
Beq.s @CheckConfig ; so just continue on.
@Do16bpp
Tst.b wombatDAFB(A6) ; If were on a Wombat, then
Bne.s @Set16bpp ; 16bpp is always possible.
Tst.b IsSlowClock(A6) ; If the CPU is running at 25MHz,
Bne.s @16bppGate ; then just look at pRAM.
Move.l DAFB_Test(A3),D0 ; Get the DAFBTest register.
Andi.w #$0FFF,D0 ; Strip off the junk.
Moveq #9,D1 ; Get the amount to shift.
Lsr.w D1,D0 ; Shift in the version number.
Cmp.b #DAFB3Vers,D0 ; If we dont have a DAFB 3,
Blt.s @16bppGate ; then just look at pRAM.
@Set16bpp Bset #spAllow16bpp,SP_Flags(A2) ; Otherwise, unblock 16bpp…
Bra.s @SkipGate ; …and skip the gate.
@16bppGate Btst #spAllow16bpp,SP_Flags(A2) ; If we are blocking usage of 16bpp,
Beq.s @CheckConfig ; the just continue with the config check.
@SkipGate Cmp.b #sRsrc_NeverMatch,D5 ; If the no-connect sRsrc is in use,
Beq.s @CheckConfig ; then just go on.
LEA DAFB16bppTable,A0 ; Point to DAFB16bpp configuration table.
LEA (A0,D6*DT_Size),A0 ; Point to the entry set for this display.
MOVE.L DT_Family(A0),D7 ; Get the 16bpp family alternatives.
MOVE.B DT_Mode(A0,D2),D5 ; Get the 16bpp default spID.
Cmp.b #MinDAFB16bppSRsrc,D5 ; If D5 < MinDAFB16bppSRsrc,
Blt.s @CheckConfig ; then we didnt get a 16bpp-capable sRsrc.
Bset #spHas16bppSRsrc,SP_Flags(A2) ; Otherwise, remember that weve got a 16bpp-capable sRsrc.
Tst.b hasLin16BppCLUT(A6) ; If were not using an Antelope,
Beq.s @CheckConfig ; then just go on.
Cmp.b #sRsrc_Vid_DAFB_GSx,D5 ; If were not trying to do 1-32bpp on Rubik
Bne.s @CheckConfig ; then just go on.
Move.b #sRsrc_Vid_DAFB_GSz,D5 ; Otherwise, say we can only do 1-16bpp.
; If the last configuration matches, then D5 will be OK. The actual mode (depth) may be different, if
; (and only if) the last configuration matches. Note: We do this so that the “Welcome to Mac” screen
; looks right when switching from different configuration within the same family.
;
@CheckConfig
CMP.B SP_DfltConfig(A2),D5 ; If the configuration is not the same,
Bne.s @Reconfig ; then reset everything.
Move.b SP_Flags(A2),D0 ; Get the SP_Flags.
Lsr.b #spAltSenseEnb,D0 ; Get the AltSenseEnb bit.
Andi.b #$01,D0 ; Strip off everything else.
Move.b altSenseEnb(A6),D1 ; Get the local copy.
Cmp.b D0,D1 ; If they are not the same, then
Bne.s @SetSOG ; the sense-code changed (so set SOG).
Bra.s @WritePRam ; Otherwise, were okay.
; Configuration has changed, so set up pRAM for next time. Note: We ALWAYS write out pRam because
; the monID might have changed even though spID might not have. A good example of this
; is a NTSC or PAL encoder/decoder box vs. an NTSC or PAL display.
;
@Reconfig
MOVE.B D5,SP_DfltConfig(A2) ; Set identification configuration.
MOVE.B D5,SP_LastConfig(A2) ; Make this the current config as well.
Lea ModeTable,A0 ; Point to the table of modes.
Lea (A0,D6*MT_Size),A0 ; Get offset to right entry per display.
Move.b (A0,D2),SP_Depth(A2) ; Write out the default mode per vRam.
Tst.b sogSwitch(A6) ; If were not supposed to alter the SOG state,
Bne.s @WritePRAM ; then just go on.
@SetSOG Cmpi.b #indexedSenseVGA,D6 ; If this is a VGA-sensed display,
Beq.s @SOGOff ; then always disable sync-on-green.
Bset #spSyncOnGreen,SP_Flags(A2) ; Otherwise, set the sync-on-green flag (to enable).
Bra.s @WritePRam ;
@SOGOff Bclr #spSyncOnGreen,SP_Flags(A2) ; Clear sync-on-green flag (to disable).
@WritePRam Bclr #spFamilyChanged,SP_Flags(A2) ; Always reset the family-changed bit.
Beq.s @EndScrnChk ; If it was already reset, then go on.
Move.w #drHwDAFB,ScrnInval ; Remind ourselves to manually update the 'scrn' resource (so disk can make things right).
@EndScrnChk
LEA spBlk(A6),A0 ; Point back to spBlock.
MOVE.L A2,spsPointer(A0) ; Set up parameter block.
_sPutPRAMRec ; Write the new record out
;
; Prune the video sResources. This is straightforward for the progressive scan displays, but is
; a little tricky for the interlaced & VGA displays since they have video mode families that are
; memory dependent.
;
DAFBPruneVidSRsrcs
MOVE.B SP_LastConfig(A2),D5 ; Get current mode into D5.
TST.L D7 ; Are there family modes?
BEQ.S @StartPrune ; If zero, then none.
EndWith
;
; If there are family modes, adjust for memory size. For interlaced displays, the family mode longword
; is constructed such that the high word holds the IDs for convolved modes. Also, the low word contains
; the fullfunction spIDs (rather than the reduced RAM versions). For VGA, we use the family
; mode mechanism to swap between VGA and SuperVGA.
;
TST.B D2 ; If D2=0, then 2MB vRAM,
BEQ.S @SkipRAMAdjust ; so no need to adjust.
Cmp.b #1,D2 ; If D2=1, then 1MB vRam.
Bne.s @512KVRamAdjust ; Otherwise do 512K vRam case.
Andi.l #$FFFFFEFE,D7 ; 1MB: Keep convolved, but convert 'b' to 'a'.
Bra.s @SkipRAMAdjust ;
@512KVRamAdjust AND.L #$0000FEFE,D7 ; 512K: Turn off convolved, convert 'b' to 'a'.
@SkipRAMAdjust Tst.b wombatDAFB(A6) ; If we dont have a Wombat,
Beq.s @StartPrune ; then just go on.
Andi.l #$0000FFFF,D7 ; Otherwise, make sure convolved is off.
@StartPrune LEA ModeList,A1 ; Point to all the video modes.
MOVE.W (A1)+,D1 ; Get count of modes.
@BeginLoop MOVE.B (A1)+,spID(A0) ; Get a mode from the list and put in spBlock.
CMP.B spID(A0),D5 ; Is this the current one (the keeper)?
BEQ.S @EndLoop ;
TST.L D7 ; Test for family modes.
BEQ.S @SkipFamilies ;
MOVEQ #4-1,D3 ; Test for four family mode matches.
@LoopFamilies
CMP.B spID(A0),D7 ; Is this a match?
BEQ.S @disableIt ; If it is, then disable rather than delete.
ROL.L #8,D7 ; Shift next value into low-byte.
DBRA D3,@LoopFamilies ; If it exits from the bottom, then delete this mode.
@SkipFamilies
_sDeleteSRTRec ; Delete it.
@EndLoop DBRA D1,@BeginLoop
BRA.S ChkDAFBVidActive ; Continue
@DisableIt
MOVE.L #1,spParamData(A0) ; Setup to disable this mode.
CLR.L spsPointer(A0) ; Not a RAM sRsrc.
_SetsRsrcState ; Set it.
BRA.S @EndLoop
;
; Now that everything is set up, we need to determine whether a known configuration is out there.
; If so, we continue with the normal PrimaryInit process. Otherwise, we shut things down and
; leave.
;
ChkDAFBVidActive
CMP.B #sRsrc_NeverMatch,D5 ; If a known display is connected, then
BNE.S DAFBSetup ; start the ball rolling.
BRA DAFBExit ; Otherwise, just leave.
;
; OK, we've done all the bookkeeping. Now, load and set the DAFB parameters.
;
DAFBSetup
Lea spBlk(A6),A0 ; Point back at the spBlock on the stack.
Clr.w spID(A0) ; Start looking at spID 0, no external devices.
Clr.b spTBMask(A0) ; Only look for the board sRsrc.
Move.w #catBoard,spCategory(A0) ; Look for: catBoard,
Move.w #typBoard,spCType(A0) ; typBoard,
Clr.w spDrvrSW(A0) ; 0,
Clr.w spDrvrHW(A0) ; 0.
Clr.l spParamData(A0) ; (The board sRsrc must be enabled.)
Bset #foneslot,spParamData+3(A0) ; Limit search to slot 0.
_GetTypeSRsrc ; Get the spsPointer.
MOVE.B #sVidParmDir,spID(A0) ; Look for the video parameters dir.
_sFindStruct ;
Move.b D5,D1 ; Get the appropriate sRsrcID into D1.
Move.l DAFBFlags(A3),D0 ; Get the DAFBFlags into D0.
Btst #RadiusTPDBit,D0 ; If we dont have a RadiusTPD,
Beq.s @GetParams ; then just go on.
Btst #RadiusDevType,D0 ; If we have a Radius MonoTPD,
Beq.s @SetMonoTPD ; then say so.
Move.b #pSRsrc_Vid_DAFB_2PRdRGB,D1 ; Otherwise, say weve got…
Bra.s @GetParams ; …a Radius ColorTPD.
@SetMonoTPD Move.b #pSRsrc_Vid_DAFB_2PRdMono,D1 ;
@GetParams MOVE.B D1,spID(A0) ; Look in the directory for this config's parameters.
_sGetBlock ;
MOVE.L spResult(A0),A1 ; Get pointer to FirstVidMode set of parameters.
Move.l A1,vidParamsPtr(A6) ; Save for later.
Move.b D5,spID(A0) ; Set up to find the functional sRsrc.
_sRsrcInfo ; Get the spsPointer.
Move.b #MinorBaseOS,spID(A0) ; Set up to get the video base offset value.
_sReadLong ; Get it.
Move.l spResult(A0),D0 ; Load the vRAM base offset into D0.
Add.l D0,vRAMBaseAddr(A6) ; Add it to the vRAM base address.
; Do the hardware setup (as they appear in the DAFB parameters).
;
With DAFBVidParams,DAFBBppParams
MOVEQ #0,D0 ; Clear upper part of D0.
MOVE.L A3,A2 ; Copy DAFB base address.
; Setup Clock chip…
;
Move.b #1,clkSetup(A6) ; Say that the clock is initialized.
Bsr SetupDAFBClk ; Now, go reprogram it.
; Setup DAFB…
;
Tst.b wombatDAFB(A6) ; If were on a Wombat,
Bne.s @SetupDAFB ; then just go on.
Cmp.b #indexedSenseRubik,D6 ; If dont have a Rubik,
Bne.s @SetupDAFB ; then just go on.
Move.l #7,DAFB_VidBaseHi(A2) ; 1bpp-Rubik is weird.
Move.l #0,DAFB_VidBaseLo(A2) ;
Bra.s @SkipBaseSetup
@SetupDAFB
DAFBSetVidBaseAddr vRAMBaseAddr(A6) ; Set up the video base address.
@SkipBaseSetup
DAFBWWrite dvpRowWords,DAFB_RowWords ; Set up the RowWords.
DAFBWWrite dvpConfig,DAFB_Config ; Set up the controller.
DAFBSpeedPI ; Re-configure DAFB for right CPU speed.
; Setup Swatch…
;
DAFBWWrite dvpTimingAdj,Swatch_TimeAdj ; Set up timing adjustments.
DAFBWWrite dvpHSerr,Swatch_HSerr ; Set up horizontal timing…
DAFBWWrite dvpHlfLn,Swatch_HlfLn ;
DAFBWWrite dvpHEq,Swatch_HEq ;
DAFBWWrite dvpHSP,Swatch_HSP ;
DAFBWWrite dvpHBWay,Swatch_HBWay ;
DAFBWWrite dvpHBrst,Swatch_HBrst ;
DAFBWWrite dvpHBP,Swatch_HBP ;
DAFBWWrite dvpHAL,Swatch_HAL ;
DAFBWWrite dvpHFP,Swatch_HFP ;
DAFBWWrite dvpHPix,Swatch_HPix ;
DAFBWWrite dvpVHLine,Swatch_VHLine ; Set up vertical timing…
DAFBWWrite dvpVSync,Swatch_VSync ;
DAFBWWrite dvpVBPEq,Swatch_VBPEq ;
DAFBWWrite dvpVBP,Swatch_VBP ;
DAFBWWrite dvpVAL,Swatch_VAL ;
DAFBWWrite dvpVFP,Swatch_VFP ;
DAFBWWrite dvpVFPEq,Swatch_VFPEq ;
; ACDC configuration setup: 1bpp and both entries “black” to prevent visual artifacts until
; were ready.
;
Clr.l ACDC_AddrReg(A3) ; Tell ACDC to use PCBR0.
DAFBWWrite dvpACDCPCBR,ACDC_ConfigReg ; Set up ADCD config register.
Nop ; (DAFBs address space is non-serial.)
Tst.l ACDC_AddrReg(A3) ; Read the addr reg to make it stick (AC842A).
Moveq #0,D0 ; Clear write value.
Moveq #6-1,D1 ; Set up to clear (“black out”) both R-G-B entries.
@ClrCLUT Move.b D0,ACDC_DataReg+3(A3) ; Write out each entry.
Tst.b hasLin16BppCLUT(A6) ; (But wait at least 5
Beq.s @Next ; PixClk cycles if
Tst.b ([VIA]) ; weve got an Antelope.)
@Next Dbra D1,@ClrCLUT ; Loop until done.
; Adjust for AC842A, if necessary.
;
Tst.b has16bppACDC(A6) ; If we have dont have an AC842A,
Beq.s @EndAC842A ; then just go on.
DAFBWWrite dvpTimingAdjAMD,Swatch_TimeAdj ; Adjust TimingAdj,
DAFBWWrite dvpHALAMD,Swatch_HAL ; HAL,
DAFBWWrite dvpHFPAMD,Swatch_HFP ; HFP.
Tst.b wombatDAFB(A6) ; If we dont have a WombatDAFB,
Beq.s @EndAC842A ; then just go on.
Moveq #32,D1 ; Init Wombat TimingAdj adjustment value.
Moveq #0,D0 ; Clear this reg for good measure.
Move.w dvpACDCPCBR(A1),D0 ; Pick up the PCBR value.
Bclr #7,D0 ; Strip off the IRE-value.
Lsr.w #5,D0 ; Keep just the VidClk bits.
Move.w D0,D3 ; And save them for later.
Beq.s @AddAdj ; If zero, then were done.
Lsl.w #1,D0 ; Use VidClk bits to determine adjument.
Divu D0,D1 ; Determine adjustment (VidClk is always 0, 1, or 2; its NEVER 4).
@AddAdj Add.l D1,Swatch_TimeAdj(A2) ; Add it in.
Tst.b hasLin16BppCLUT(A6) ; If we dont have an Antelope,
Beq.s @EndAC842A ; then just go on.
Lea @AntAdjTbl,A0 ; Point to the table of Antelope adjustment values.
Move.w (A0,D3*2),D0 ; Get the appropriate adjustment value.
Add.l D0,Swatch_TimeAdj(A2) ; Adjust TimingAdj,
Add.l D0,Swatch_HAL(A2) ; HAL,
Add.l D0,Swatch_HFP(A2) ; HFP.
Bra.s @EndAC842A
@AntAdjTbl Dc.w 5,2,1 ; PixClk/1,PixClk/2,PixClk/4 TimingAdj,HAL,HFP adjustments.
@EndAC842A Adda.w #DVPHdrSize+DBPSize,A1 ; Point to the SC_Params.
Endwith
; Perform various pRAM-related adjustments…
;
With SP_Params
LEA sPRAMBlk(A6),A2 ; Re-point to sPRAM block.
; Sync On Green…
;
Tst.b wombatDAFB(A6) ; If were not on a Wombat,
Beq.s @VIASOG ; then use the VIA SOG.
Move.l DAFB_ClkCfg(A3),D0 ; Get the current Clock config value.
Btst #spSyncOnGreen,SP_Flags(A2) ; If were supposed to put sync on green,
Bne.s @EnableSyncOnGreen ; then hop to it.
Moveq #0,D1 ; Otherwise, set up for disabling.
Bra.s @SyncOnGreenCommon
@EnableSyncOnGreen
Moveq #1,D1 ; Set up for enabling.
@SyncOnGreenCommon
Bfins D1,D0{dafbSyncOnGreen:1} ; Toggle the sync-on-green bit appropriately,
Move.l D0,DAFB_ClkCfg(A3) ; apply it.
Bra.s @DoPageMode
@VIASOG Btst #spSyncOnGreen,SP_Flags(A2) ; If were supposed to put sync on green, then just
Bne.s @DoPageMode ; go on because we default to sync on green.
Move.l VIA2,A0 ; Otherwise, point to VIA2, and
Bclr #v2SyncOnGreen,vBufA(A0) ; disable sync on green.
; Page Mode…
;
@DoPageMode
Move.l DAFB_Config(A3),D0 ; Read the DAFBConfig register.
Bfextu D0{dafbWrdIntBit:1},D0 ; If word-interleave is on,
Bne.s @DisableIt ; then ALWAYS disable page mode.
Btst #spPageMode,SP_Flags(A2) ; If were not supposed to enable page mode,
Beq.s @DoReset ; then just go on since the hardware comes that way.
Moveq #1,D0 ; Otherwise, set up to enable page mode,
Bra.s @HitPageMode ; and do it.
@DisableIt Moveq #0,D0 ; Set up to disable page mode,
@HitPageMode Move.l D0,DAFB_PgMdEn(A3) ; and do it.
Endwith
; Everything's configured, so now reset DAFB
;
@DoReset
Move.l A3,A2 ; Copy the DAFBbase address.
DAFBUnIdle ; Un-idle and…
DAFBReset ; …reset DAFB.
; Do screen and CLUT setup…
;
Move.l vRAMBaseAddr(A6),A2 ; Point A2 at the framebuffer base address.
Move.l vidParamsPtr(A6),A0 ; Point A0 at the vidParams.
; Do top of screen…
;
; Note that SC_BorderHeight is adjusted to work correctly for both bordered and non-bordered screens.
; Specifically, this constant is not “-1”-adjusted for Dbra, so we jump into the tail end of the Dbra
; loop and therefore have the “right” thing happen. My head hurts now, and yours should, too!
;
; Note: This routine only works for screens whose boundaries are even multiples of 64 (due to our
; use of “doublelongs). Real PALST mode is 614x460, but we use 640x480 for for now. This
; keeps things fast. If we have to add “runs” to fix this problem, we will.
;
; This code is used in the drivers GrayScreen (DAFBGrayScreen), as well. Fixes should be applied
; to both places. Wouldnt it be neat if there was some sort of video “toolbox” for code that
; is shared among the drivers and primary inits? Sure is easy to miss things when the
; same code is spread across multiple files.
;
With SC_Params,DAFBVidParams
Moveq #IndexedBlack,D3 ; Get black into a convenient register.
Cmp.b #indexedSenseRubik,D6 ; If were on a Rubik display, then
Beq.s @FixRubik1bpp ; apply fix.
Cmp.b #sRsrc_Vid_DAFB_NTSCconvST,D5 ; If were on an NTSC convolved display,
Beq.s @FixNTSCPALTop ; then apply fix.
Cmp.b #sRsrc_Vid_DAFB_NTSCconvFF,D5
Beq.s @FixNTSCPALTop
Cmp.b #sRsrc_Vid_DAFB_NTSCconvSTx,D5
Beq.s @FixNTSCPALTop
Cmp.b #sRsrc_Vid_DAFB_NTSCconvFFx,D5
Beq.s @FixNTSCPALTop
Cmp.b #sRsrc_Vid_DAFB_PALconvST,D5 ; If were on a PAL convolved display,
Beq.s @FixNTSCPALTop ; then apply fix.
Cmp.b #sRsrc_Vid_DAFB_PALconvFF,D5
Beq.s @FixNTSCPALTop
Cmp.b #sRsrc_Vid_DAFB_PALconvSTx,D5
Beq.s @FixNTSCPALTop
Cmp.b #sRsrc_Vid_DAFB_PALconvFFx,D5
Beq.s @FixNTSCPALTop
Bra.s @ScreenStart
@FixRubik1bpp Move.w #DAFB_512_RB,D0 ; Fix first-line problem on Rubik displays.
Bra.s @FixRow
@FixNTSCPALTop Move.w #DAFB_1024_RB,D0 ; Create “false” first line on NTSC/PAL convolved
; displays.
@FixRow Suba D0,A2 ; Point back one full line.
Lsr.w #2,D0 ; Make loop counter long-word based.
Subq #1,D0 ; Subtract 1 for Dbra.
@BlastRow Move.l D3,(A2)+ ; Blast black to screen.
Dbra D0,@BlastRow
@ScreenStart Move.w SC_BorderHeight(A1),D1 ; Get number of rows (not -1) to blast back on top.
Bra.s @TopSecPrime ;
@TopSecFill_V Move.w SC_BorderWidth(A1),D0 ; Get number of longs (-1) to blast black in row.
@TopSecFill_H Move.l D3,(A2)+ ; Blast black to screen.
Dbra D0,@TopSecFill_H
Adda.w SC_SkipFactor(A1),A2 ; Skip to start of next row.
@TopSecPrime Dbra D1,@TopSecFill_V
; Do middle of screen…
;
; Unlike the top part, there is always a “middle.” However, there might be a left and right side (when the
; border is appropriate), so the not “-1”-adjusted for Dbra comments that are listed above apply horizontally
; here.
;
Move.l #OneBitGray,D4 ; Get the gray pattern (for the active middle).
Move.w dvpNumRows(A0),D1 ; Get number of rows (-1) in middle of screen.
@MidSecFill_V
Move.w SC_BorderSide(A1),D0 ; Get number of longs (not -1) to blast black in row.
Bra.s @MidSecPrime_L
@MidSecFill_L Move.l D3,(A2)+ ; Blast black to screen.
@MidSecPrime_L Dbra D0,@MidSecFill_L
Move.w SC_ActiveWidth(A1),D0 ; Get the number of doublelongs (-1) for active middle
@MidActFill_H Move.l D4,(A2)+ ; Fill the active section with gray.
Cmp.b #sRsrc_Vid_DAFB_SVGAa,D5 ; Skip if SuperVGA (800x600 is not an
Beq.s @SkipDouble ; even multiple of 64, but it is an)
Cmp.b #sRsrc_Vid_DAFB_SVGAb,D5 ; even multiple of 32).
Beq.s @SkipDouble ;
Cmp.b #sRsrc_Vid_DAFB_SVGAax,D5 ;
Beq.s @SkipDouble ;
Cmp.b #sRsrc_Vid_DAFB_SVGAbx,D5 ;
Beq.s @SkipDouble ;
Move.l D4,(A2)+ ; Do second half where applicable.
@SkipDouble Dbra D0,@MidActFill_H
Not.l D4 ; Invert for NEXT line.
Move.w SC_BorderSide(A1),D0 ; Get number of longs (not -1) to blast black in row.
Bra.s @MidSecPrime_R
@MidSecFill_R Move.l D3,(A2)+ ; Blast black to screen
@MidSecPrime_R Dbra D0,@MidSecFill_R
Adda.w SC_SkipFactor(A1),A2 ; Move to NEXT line.
Dbra D1,@MidSecFill_V
; Do bottom of screen…
;
Move.w SC_BorderHeight(A1),D1 ; Get number of rows (not -1) to blast back on bottom.
Cmp.b #sRsrc_Vid_DAFB_NTSCconvST,D5 ; If were on an NTSC convolved display,
Beq.s @FixNTSCPALBot ; then apply fix.
Cmp.b #sRsrc_Vid_DAFB_NTSCconvFF,D5
Beq.s @FixNTSCPALBot
Cmp.b #sRsrc_Vid_DAFB_NTSCconvSTx,D5
Beq.s @FixNTSCPALBot
Cmp.b #sRsrc_Vid_DAFB_NTSCconvFFx,D5
Beq.s @FixNTSCPALBot
Cmp.b #sRsrc_Vid_DAFB_PALconvST,D5 ; If were on a PAL convolved display,
Beq.s @FixNTSCPALBot ; then apply fix.
Cmp.b #sRsrc_Vid_DAFB_PALconvFF,D5
Beq.s @FixNTSCPALBot
Cmp.b #sRsrc_Vid_DAFB_PALconvSTx,D5
Beq.s @FixNTSCPALBot
Cmp.b #sRsrc_Vid_DAFB_PALconvFFx,D5
Beq.s @FixNTSCPALBot
Bra.s @BotStart
@FixNTSCPALBot Addq #1,D1 ; For convolved interlace displays, we need to
; blacken the “false” bottom.
@BotStart Bra.s @BotSecPrime ;
@BotSecFill_V Move.w SC_BorderWidth(A1),D0 ; Get number of longs (-1) to blast black in row.
@BotSecFill_H Move.l D3,(A2)+ ; Blast black to screen.
Dbra D0,@BotSecFill_H
Adda.w SC_SkipFactor(A1),A2 ; Skip to start of next row.
@BotSecPrime Dbra D1,@BotSecFill_V
EndWith ; SC_Parms
; Set up a [white, black] gamma-corrected color table.
;
With MiniGamma
Move.w D6,D1 ; Get the appropriate index (.w) into D1.
Move.l DAFBFlags(A3),D0 ; Get the DAFBFlags into D0.
Btst #RadiusTPDBit,D0 ; If we dont have a RadiusTPD,
Beq.s @GetGamma ; then just go on.
Btst #RadiusDevType,D0 ; If we dont have a MonoTPD,
Bne.s @GetGamma ; then just go on.
Move.w #pIndexRdMono,D1 ; Otherwise, use Radius MonoTPD gamma.
@GetGamma Lea MiniGammaTable,A0 ; Point to start of the mini gamma table.
Lea (A0,D1*GT_Size),A0 ; Get offset to right entry.
Clr.l ACDC_AddrReg(A3) ; Start at position zero in the CLUT.
Adda #(ACDC_DataReg+3),A3 ; Point to CLUT data register directly.
Tst.b hasLin16BppCLUT(A6) ; If we dont have an Antelope,
Beq.s @EndWait ; then just go on.
Tst.b ([VIA]) ; Otherwise, wait a µSec.
@EndWait
; Write gamma-corrected white entry to CLUT…
;
Move.b whiteRed(A0),(A3)
Move.b whiteGreen(A0),(A3)
Move.b whiteBlue(A0),(A3)
Tst.b hasLin16BppCLUT(A6) ; If we dont have an Antelope,
Beq.s @EndWhite ; then just go on.
Tst.b ([VIA]) ; Otherwise, wait a µSec.
@EndWhite
; Write gamma-corrected black entry to CLUT…
;
Move.b blackRed(A0),(A3)
Move.b blackGreen(A0),(A3)
Move.b blackBlue(A0),(A3)
EndWith
; Dispose of vidParams and restore addressing mode…
;
Move.l vidParamsPtr(A6),A0 ; Dispose of video parameter block.
_DisposPtr
DAFBExit
MOVE.B saveMMUMode(A6),D0 ; Get the old memory mode back, and
_SwapMMUMode ; restore it.
Rts
;_________________________________________________________________________
;
; Utility code and tables
;
;_________________________________________________________________________
;
; This subroutine grays the frame buffer for simple built-in videos. On entry, A1 should point the simple
; screen size parameters. For BlastAddr, A0 should point to the framebuffer base.
;
BlastParams Record 0
skipFactor Ds.w 1 ; Number of bytes to skip after the active part of the line has been drawn.
numLWords Ds.w 1 ; Number of longwords per row to clear (zero based).
numRows Ds.w 1 ; Number of rows to clear (zero based).
BlastParamsSize Equ *
Endr
With ProductInfo,VideoInfo,BlastParams
Blast
MOVEA.L UnivInfoPtr,A0 ; point to the ProductInfo record <2.2>
ADDA.L VideoInfoPtr(a0),A0 ; point to the VideoInfo record <2.2>
MOVE.L VRAMLogAddr32(a0),A0 ; get the frame buffer base address <2.2>
BlastAddr
MOVE.L #OneBitGray,D4 ; get the gray pattern
MOVE.W skipFactor(A1),D3 ; get the skipfactor
MOVE.W numRows(A1),D2 ; get the # of rows - 1
Moveq #true32b,D0 ; Set up to flip into 32-bit addressing mode.
_SwapMMUMode
@NxtRow MOVE.W numLWords(A1),D1 ; get the # of longwords/row - 1
@NxtWord MOVE.L D4,(A0)+ ; write gray
DBRA D1,@NxtWord ; for each scanline
ADDA D3,A0 ; add in the skip factor <H38>
NOT.L D4 ; invert pattern on next row
DBRA D2,@NxtRow ; for each row
_SwapMMUMode ; Restore previous mode.
RTS
EndWith
; This subroutine reads the DAFB sense lines. On entry, A2 should point to the DAFB base address, D4
; should contain $03, $05, $06, or $07 to indicate the type of extended sense were doing, and
; the CPU should have been put into 32-bit addressing mode. On exit, D4 contains the appropriate
; extended sense code.
;
; Note: The idea behind the extended-sense-line ($07) algorithm is as follows: First, drive sense line
; “a” and read the values of “b” and “c.” Next, drive sense line “b” and read the values of “a”
; and “c.” Finally, drive sense line “c” and read the values of “a” and “b.” In this way, a
; six-bit number of the form bc/ac/ab is generated. The other extended-sense algorithms are
; identical to that of $07, except one of the three lines doesnt need to be driven. For example,
; with $03, “a” doesnt need to be driven. With $05, “b” doesnt need to be driven, and
; with $06, “c” doesnt need to be driven.
;
DoDAFBExtendedSense
Movem.l D0-D1,-(Sp) ; Save work registers.
Moveq #0,D1 ; Use D1 to store extended-sense code.
Moveq #0,D0 ; Use D0 as temp from reads.
; Drive a, Read bc
;
Cmp.b #indexedSense2P,D4 ; If this is not a type-3 extended sense,
Bne.s @DriveA ; then go ahead and drive A.
Move.b D4,D0 ; Otherwise, write out the assumed value,
Bra.s @EndA ; and go on.
@DriveA Move.l #dafbAMask,DAFB_Sense(A2) ; abc <- 011
DAFBReadSenseLines D0 ; abc -> ABC
Andi.b #dafbAMask,D0 ; 0BC
@EndA Move.b D0,D1 ; 00 00 BC
Lsl.b #2,D1 ; 00 BC 00
; Drive b, Read ac
;
Cmp.b #indexedSenseRGBFP,D4 ; If this is not a type-5 extended sense,
Bne.s @DriveB ; then go ahead and drive B.
Move.b D4,D0 ; Otherwise, write out the assumed value,
Bra.s @EndB ; and go on.
@DriveB Move.l #dafbBMask,DAFB_Sense(A2) ; abc <- 101
DAFBReadSenseLines D0 ; abc -> ABC
Andi.b #dafbBMask,D0 ; A0C
@EndB Bclr #dafbSenseLineA,D0 ; A0C becomes
Beq.s @OrIn ; A0C or
Bset #dafbSenseLineB,D0 ; A1C
@OrIn Or.b D0,D1 ; 00 BC AC
Lsl.b #2,D1 ; BC AC 00
; Drive c, Read ab
;
Cmp.b #indexedSenseHR,D4 ; If this is not a type-6 extened sense,
Bne.s @DriveC ; then go ahead and drive C.
Move.b D4,D0 ; Otherwise, write out the assumed value,
Bra.s @EndC ; and go on.
@DriveC Move.l #dafbCMask,DAFB_Sense(A2) ; abc -> 110
DAFBReadSenseLines D0 ; abc <- ABC
Andi.b #dafbCMask,D0 ; AB0
@EndC Lsr.b #1,D0 ; 0AB
Or.b D0,D1 ; BC AC AB
Move.b D1,D4 ; Save the extended-sense code.
Movem.l (Sp)+,D0-D1 ; Restore work registers.
Rts ; Return to caller.
; Spike, Eclipse, and Zydeco use the NSC-8531 for all dot clocks other than 100 MHz, and Wombat CPUs
; exclusively use the NSC-8534. The following code set up the clock (using the DAFBVidParams)
; the type of machine were running on. Note: This routine assumes that A2 is pointining to
; the DAFB base address, and that A1 is point to the DAFBVidParams; A1/A2 are preserved.
;
With DAFBVidParams
SetupDAFBClk
DAFBSpeedPI A2 ; Configure DAFB for the right CPU speed.
Tst.b clkSetup(A6) ; If the clock is already set up,
Bne.s @KeepClkSel ; then dont reset the ClkSel bit.
DAFBWWrite dvpClkCfg,DAFB_ClkCfg ; Set up the clocking.
Bra.s @SetupClk ;
@KeepClkSel Move.l DAFB_ClkCfg(A2),D0 ; Pick up the ClkCfg reg.
Andi.l #$00000100,D0 ; Clear everything but the ClkSel bit.
DAFBWWrite dvpClkCfg,DAFB_ClkCfg ; Set up the clocking.
Or.l D0,DAFB_ClkCfg(A2) ; Make sure ClkSel is correct.
@SetupClk ADDA #Clk_BaseOffset,A2 ; Advance to Clock chip base.
Tst.b wombatDAFB(A6) ; If we have a Wombat,
Bne.s @Do8534 ; then setup for the Wombat clock.
Move.w #Clk_ParmSize1-1,D1 ; Set up to hit only the non-common 8531 regs.
@ClockLoop8531A MOVE.B (A1)+,D0 ; Get the parameter.
MOVE.L D0,(A2) ; Write it out.
ADDA.W #$10,A2 ; Increment to next register,
DBRA D1,@ClockLoop8531A ; for each register.
Lea DAFB8531Comm,A1 ; Point to the common 8531 params.
Move.w #(Clk_ParmSize-Clk_ParmSize1)-1,D1 ; Load our counter.
@ClockLoop8531B Move.b (A1)+,D0 ; Get the parameter.
Move.l D0,(A2) ; Write it out.
Move.w #175-1,D3 ; Otherwise, we need to wait for 150-200 µs <SM10>
@WaitLoop0 Tst.b ([VIA]) ; in order for the CPO select to take effect. <SM10>
Dbra D3,@WaitLoop0 ; <SM10>
Adda.w #$10,A2 ; Increment to next register,
Dbra D1,@ClockLoop8531B ; for each register.
Bra.s @Done ; (Skip the 8534 code.)
@Do8534
Moveq #21-1,D1 ; The 8534 is brain-damaged, so we have to write to it (10x2)+1 times!
@Loop8534 Adda #Clk_ParmSize1,A1 ; Point past the 8531 clock params.
Eori.w #$0008,(A1) ; Toggle the 8534 reset-bit.
Cmp.w #21-20,D1 ; If were not on the last iteration,
Bne.s @SwapIt ; then just keep going.
Eori.w #$0008,(A1) ; Toggle the 8534 reset-bit.
Ori.w #$0100,(A1) ; Set the CPO bit.
@SwapIt Swap D1 ; Save the iteration count in the hi-order word.
Move.w #3-1,D1 ; We have to write out a 47-bit number, 3 serialized words at a time.
@WordLoop Moveq #16-1,D3 ; Number of bits (1-words worth) to shift in per param.
@AtLast Moveq #0,D0 ; Clear both halves of our param register.
Move.w (A1)+,D0 ; Get the next param.
Swap D0 ; Get it into the hi-order word.
@WriteABit Rol.l #1,D0 ; Get the bit we want, where we want it.
Move.b D0,3(A2) ; Write it out to the clock chip.
Nop ; (DAFB space is non-serial.)
Dbra D3,@WriteABit ; Loop until done.
Cmp.w #3-2,D1 ; If were not on the last iteration,
Bne.s @LoopIt ; then just keep going.
Moveq #14-1,D3 ; Otherwise, we have to special-case the last (the 47th) bit.
Dbra D1,@AtLast ;
@LoopIt Dbra D1,@WordLoop ; Loop until done.
Rol.l #1,D0 ; Get the last bit.
Move.b D0,$10+3(A2) ; Tell the clock chip to use these bits.
Nop ; (DAFB space is non-serial.)
Swap D1 ; Get back the iteration count.
Move.l vidParamsPtr(A6),A1 ; Re-point to the vidparams.
Btst #0,D1 ; If this is not at the end of one of our pairs,
Beq.s @NotEven ; then just go on.
Move.w #175-1,D0 ; Otherwise, we need to wait for 150-200 µs
@WaitLoop Tst.b ([VIA]) ; in order for the CPO select to take effect.
Dbra D0,@WaitLoop ;
@NotEven Dbra D1,@Loop8534 ; Loop until done.
@Done
Move.l vidParamsPtr(A6),A1 ; Re-point to the vidparams.
Move.l A3,A2 ; Re-point to DAFB base address.
Rts
Endwith
;_________________________________________________________________________
ALIGN 4
;
; Here's a table of the different spID's that the board sRsrc might have. It's used at the
; beginning of this code to set up the appropriate board sRsrc
;
spIDTbl DC.W spIDTblEnd-spIDTblStart-2 ; this is the count of all the modes (-1 for DBRA)
spIDTblStart
DC.B sRsrc_BdMacII,sRsrc_BdMacIIx,sRsrc_BdMacIIcx
DC.B sRsrc_BdMacSE30,sRsrc_BdMacIIci,sRsrc_BdMacIIfx
DC.B sRsrc_BdErickson,sRsrc_BdElsie,sRsrc_BdEclipse,sRsrc_BdLCII ; <SM4>
DC.B sRsrc_BdTIM,sRsrc_BdSpike
Dc.b sRsrc_BdApollo
Dc.b sRsrc_BdTIMLC
Dc.b sRsrc_BdZydeco
Dc.b sRsrc_BdDbLite25,sRsrc_BdDBLite33,sRsrc_BdDBLite16,sRsrc_BdDBLite20
Dc.b sRsrc_BdWombat20,sRsrc_BdWombat25,sRsrc_BdWombat33,sRsrc_BdWombat40
Dc.b sRsrc_BdWombat33F,sRsrc_BdWombat40F
Dc.b sRsrc_BdWLCD20,sRsrc_BdWLCD25,sRsrc_BdWLCD33
Dc.b sRsrc_BdDartanian,sRsrc_BdDartanianLC
Dc.b sRsrc_BdSTPQ700 ; STP cards <SM23>
Dc.b sRsrc_BdSTPQ900 ; STP cards <SM23>
Dc.b sRsrc_BdSTPQ950 ; STP cards <SM23>
Dc.b sRsrc_BdSTPC610 ; STP cards <SM23>
Dc.b sRsrc_BdSTPC650 ; STP cards <SM23>
Dc.b sRsrc_BdSTPQ610 ; STP cards <SM23>
Dc.b sRsrc_BdSTPQ650 ; STP cards <SM23>
Dc.b sRsrc_BdSTPQ800 ; STP cards <SM23>
IF forSmurf THEN ; <SM21>
Dc.b sRsrc_BdRiscCentris610 ; SMURF cards <SM18>
Dc.b sRsrc_BdRiscCentris650 ; SMURF cards <SM18>
Dc.b sRsrc_BdRiscQuadra800 ; SMURF cards <SM18>
Dc.b sRsrc_BdRiscQuadra700 ; SMURF cards <SM18>
Dc.b sRsrc_BdRiscQuadra900 ; SMURF cards <SM18>
Dc.b sRsrc_BdRiscQuadra950 ; SMURF cards <SM18>
Dc.b sRsrc_BdRiscQuadra610 ; SMURF cards <SM20>
Dc.b sRsrc_BdRiscQuadra650 ; SMURF cards <SM20>
ENDIF
Dc.b 0,0
spIDTblEnd
ALIGN 4
; Here are the tables for pruning the CPU sResources…
;
boxTable030 Dc.w boxTable030End-boxTable030Start-1 ; table size
boxTable030Start
Dc.b boxMacII,boxMacLC ; goofy (these are 020 CPUs)
Dc.b boxMacIIx,boxMacIIcx,boxSE30
Dc.b boxMacIIfx
Dc.b boxPowerBook170
Dc.b boxPowerBookDuo210,boxPowerBookDuo230,boxDBLite20,boxPowerBookDuo250
Dc.b boxPowerBook140,boxPowerBook160,boxPowerBook180
Dc.b boxMacIIci,boxMacIIsi
If ApolloSupported Then
Dc.b boxClassicII
Endif
boxTable030End
boxTable040 Dc.w boxTable040End-boxTable040Start-3 ; table size
boxTable040Start
Dc.b boxQuadra700,boxQuadra900,boxQuadra950
;Dc.b boxWombat20,boxWombat25,boxWombat33,boxWombat40
;Dc.b boxWombat33F,boxWombat40F
;Dc.b boxWLCD20,boxWLCD25,boxWLCDc1,boxWLCD33
;Dc.b boxPrimus20,boxPrimus25,boxPrimus33
;Dc.b boxOptimus20,boxOptimus25,boxOptimus33
;Dc.b boxAladdin20,boxAladdin25,boxAladdin33
Dc.b boxMalcolm25,boxMalcolm33
Dc.b boxSlimus25,boxSlimus33
Dc.b boxBlackbird,boxBlackbirdLC,boxBlackbirdBFD
Dc.b boxYeagerG,boxYeagerC
Dc.b 0,0
boxTable040End
ALIGN 4
;
; Some simple screen size parameters. See Blast above for the meaning of each of the parameters.
;
pFPParms DC.W 0,(OBMFPRB/4)-1,defmBounds_BFP-1
pGSParms DC.W 0,(OBMGSRB/4)-1,defmBounds_BGS-1
pHRParms DC.W 0,(OBMHRRB/4)-1,defmBounds_BHR-1
pSEParms DC.W 0,(OBMSERB/4)-1,defmBounds_BSE-1
pLCDParms DC.W 0,(OBMLCDRB/4)-1,defmBounds_BLCD-1
pApolloParms Dc.w 0,(OBMApolloRB/4)-1,defmBounds_BApollo-1
; Screen graying parameters for V8 1024 rowbytes
;
pVGAParms DC.W (V8_1024_RB-(defmBounds_RVGA/8)),(defmBounds_RVGA/32)-1,defmBounds_BVGA-1
pV8HRParms DC.W (V8_1024_RB-(defmBounds_RHR/8)),(defmBounds_RHR/32)-1,defmBounds_BHR-1
; we need to treat this mode as a special case since 560 is not evenly divisible by 32!
;
pV8A2Parms DC.W (V8_1024_RB-((defmBounds_RA2Em+16)/8)),((defmBounds_RA2Em+16)/32)-1,defmBounds_BA2Em-1
; screen graying parameters for V8 512 rowbytes
;
pVGAShortParms DC.W (V8_512_RB-(defmBounds_RVGA/8)),(defmBounds_RVGA/32)-1,defmBounds_BVGA-1
pV8HRShortParms DC.W (V8_512_RB-(defmBounds_RHR/8)),(defmBounds_RHR/32)-1,defmBounds_BHR-1
pV8A2ShortParms DC.W (V8_512_RB-((defmBounds_RA2Em+16)/8)),((defmBounds_RA2Em+16)/32)-1,defmBounds_BA2Em-1
ALIGN 4
;
; Video spID mode list. Here they all are in byte size. The first word of the table is the count
; of legal modes on all machines, followed by a list of all functional spIDs.
;
; Note that id $80 should never be in this list to avoid conflicts with the implementation of
; Prune above. This could be worked around in the code, but is not a problem here since $80
; is the CPU sRsrc list
;
ModeList DC.W MLEnd-MLStart-2 ; block size
MLStart
;
; V8 sRsrcs (LC)
;
DC.B sRsrc_Vid_V8_GSa,sRsrc_Vid_V8_GSb
DC.B sRsrc_Vid_V8_A2Ema,sRsrc_Vid_V8_A2Emb
DC.B sRsrc_Vid_V8_HRa,sRsrc_Vid_V8_HRb
DC.B sRsrc_Vid_V8_VGAa,sRsrc_Vid_V8_VGAb
;
; RBV sRsrcs (IIci/si)
;
DC.B sRsrc_VidRbvHRa,sRsrc_VidRbvFPa,sRsrc_VidRbvGSa,sRsrc_VidRbvSEa
DC.B sRsrc_VidRbvHRb,sRsrc_VidRbvHRc,sRsrc_VidRbvHRd
DC.B sRsrc_VidRbvFPb,sRsrc_VidRbvFPc
DC.B sRsrc_VidRbvGSb,sRsrc_VidRbvGSc,sRsrc_VidRbvGSd
DC.B sRsrc_VidRbvSEb,sRsrc_VidRbvSEc,sRsrc_VidRbvSEd
;
; DAFB sRsrcs (Spike/Eclipse/Zydeco)
;
DC.B sRsrc_Vid_DAFB_FPa,sRsrc_Vid_DAFB_FPb,sRsrc_Vid_DAFB_GSa,sRsrc_Vid_DAFB_GSb ; <4>
DC.B sRsrc_Vid_DAFB_2Pa,sRsrc_Vid_DAFB_2Pb,sRsrc_Vid_DAFB_LPa,sRsrc_Vid_DAFB_LPb ; <4>
DC.B sRsrc_Vid_DAFB_HRa,sRsrc_Vid_DAFB_HRb,sRsrc_Vid_DAFB_VGAa,sRsrc_Vid_DAFB_VGAb ; <4>
DC.B sRsrc_Vid_DAFB_RGBFPa,sRsrc_Vid_DAFB_RGBFPb,sRsrc_Vid_DAFB_RGB2Pa,sRsrc_Vid_DAFB_RGB2Pb ; <6>
DC.B sRsrc_Vid_DAFB_NTSCconvST ; <4>
DC.B sRsrc_Vid_DAFB_NTSCSTa,sRsrc_Vid_DAFB_NTSCSTb ; <4>
DC.B sRsrc_Vid_DAFB_NTSCconvFF ; <4>
DC.B sRsrc_Vid_DAFB_NTSCFFa,sRsrc_Vid_DAFB_NTSCFFb ; <4>
DC.B sRsrc_Vid_DAFB_PALconvST ; <4>
DC.B sRsrc_Vid_DAFB_PALSTa,sRsrc_Vid_DAFB_PALSTb ; <4>
DC.B sRsrc_Vid_DAFB_PALconvFF ; <4>
DC.B sRsrc_Vid_DAFB_PALFFa,sRsrc_Vid_DAFB_PALFFb ; <4>
Dc.b sRsrc_Vid_DAFB_SVGAa,sRsrc_Vid_DAFB_SVGAb ;
Dc.b sRsrc_Vid_DAFB_19a,sRsrc_Vid_DAFB_19b ;
;
; DAFB sRsrcs (Condor/Zydeco)
;
Dc.b sRsrc_Vid_DAFB_NTSCconvSTx,sRsrc_Vid_DAFB_NTSCconvFFx
Dc.b sRsrc_Vid_DAFB_PALconvSTx,sRsrc_Vid_DAFB_PALconvFFx
Dc.b sRsrc_VID_DAFB_HRax,sRsrc_VID_DAFB_HRbx
Dc.b sRsrc_VID_DAFB_VGAax,sRsrc_VID_DAFB_VGAbx
Dc.b sRsrc_VID_DAFB_LPax,sRsrc_VID_DAFB_LPbx
Dc.b sRsrc_VID_DAFB_SVGAax,sRsrc_VID_DAFB_SVGAbx
Dc.b sRsrc_VID_DAFB_GSx,sRsrc_VID_DAFB_GSz
Dc.b sRsrc_Vid_DAFB_RGBFPbx,sRsrc_Vid_DAFB_RGB2Pbx
Dc.b sRsrc_Vid_DAFB_NTSCSTax,sRsrc_Vid_DAFB_NTSCSTbx
Dc.b sRsrc_Vid_DAFB_NTSCFFax,sRsrc_Vid_DAFB_NTSCFFbx
Dc.b sRsrc_Vid_DAFB_PALSTax,sRsrc_Vid_DAFB_PALSTbx
Dc.b sRsrc_Vid_DAFB_PALFFax,sRsrc_Vid_DAFB_PALFFbx
Dc.b sRsrc_Vid_DAFB_19bx
;
; Misc sRsrcs
;
DC.B sRsrc_Vid_Tim_LCD
Dc.b sRsrc_Vid_GSC_LCD
Dc.b sRsrc_Vid_Apollo
Dc.b 0
MLEnd
ALIGN 4
; <4>
; This is the table that translates monitor and memory configuration information to the appropriate <4>
; DAFB spID. Here's the format - the table is grouped by monitor type. For each monitor type, <4>
; there's a longword which calls out the video mode family members of this mode. If there aren't <4>
; any alternate modes, then this value is zero. The next byte is a set of flags for properties of <4>
; this display. No flags are defined at this time. The next three bytes are the 2MB, 1MB, and 512K <4>
; default spIDs, respectively. <4>
; <4>
; Here's a further note on the video family info. These only occur in the interlaced display modes. <4>
; There's a bit of special handling on these values since convolution only works with four banks <4>
; of vRAM (i.e., the 2MB configuration). If there's less RAM present, the DAFB pruning routine <4>
; makes special allowances for it. <4>
; <4>
; Here's field offsets in the DAFBTable record. We can't use a RECORD definition here since it would not <4>
; be possible to index in the mode field <4>
DT_Family EQU 0 ; [4 bytes] concatenated spIDs of alternate video mode family members <4>
DT_Misc EQU 4 ; [1 byte] miscellaneous modal flag word <4>
DT_Mode EQU 5 ; [3 bytes] spID of the preferred mode, one for each memory configuration <4>
DAFBTable ; <4>
; Family Misc Modes: 2MB, 1MB, 512K vRam <4>
;---------------------------------------------------------------------------------------------------- <4>
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_RGB2Pb,sRsrc_Vid_DAFB_RGB2Pb,sRsrc_Vid_DAFB_RGB2Pa ; Vesuvio <4>
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_FPb,sRsrc_Vid_DAFB_FPb,sRsrc_Vid_DAFB_FPa ; Mono Full-Page <4>
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_GSb,sRsrc_Vid_DAFB_GSb,sRsrc_Vid_DAFB_GSa ; Rubik <4>
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_2Pb,sRsrc_Vid_DAFB_2Pb,sRsrc_Vid_DAFB_2Pa ; Two-Page <4>
DC.B sRsrc_Vid_DAFB_NTSCconvST, \ ; <4>
sRsrc_Vid_DAFB_NTSCconvFF, \ ; <4>
sRsrc_Vid_DAFB_NTSCSTb, \ ; <4>
sRsrc_Vid_DAFB_NTSCFFb, \ ; <4>
0, sRsrc_Vid_DAFB_NTSCSTb,sRsrc_Vid_DAFB_NTSCSTa,sRsrc_Vid_DAFB_NTSCSTa ; NTSC <4>
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_RGBFPb,sRsrc_Vid_DAFB_RGBFPb,sRsrc_Vid_DAFB_RGBFPa ; RGB Full-Page <4>
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_HRb,sRsrc_Vid_DAFB_HRa,sRsrc_Vid_DAFB_HRa ; High-Res RGB/Mono <4>
;••• More configuration stuff here for extended-sense displays… ••• <4>
DC.B 0,0,0,0, 0, sRsrc_NeverMatch,sRsrc_NeverMatch,sRsrc_NeverMatch ; No-Connect
DC.B 0,0, \
sRsrc_Vid_DAFB_VGAb, \
sRsrc_Vid_DAFB_SVGAb, \
0, sRsrc_Vid_DAFB_VGAb,sRsrc_Vid_DAFB_VGAa,sRsrc_Vid_DAFB_VGAa ; VGA <7>
DC.B sRsrc_Vid_DAFB_PALconvST, \ ; <7>
sRsrc_Vid_DAFB_PALconvFF, \ ; <7>
sRsrc_Vid_DAFB_PALSTb, \ ; <7>
sRsrc_Vid_DAFB_PALFFb, \ ; <7>
0, sRsrc_Vid_DAFB_PALSTb,sRsrc_Vid_DAFB_PALSTa,sRsrc_Vid_DAFB_PALSTa ; PAL <7>
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_LPb,sRsrc_Vid_DAFB_LPa,sRsrc_Vid_DAFB_LPa ; Goldfish <7>
Dc.b 0,0,0,0, 0, sRsrc_Vid_DAFB_19b,sRsrc_Vid_DAFB_19b,sRsrc_Vid_DAFB_19a ; 19"
Align 4
;
; The DAFB16bpp table is identical to the DAFB table except that only the 1 Meg and 2 Meg configurations are meaningful,
; since none of the displays supported by DAFB can do 16bpp in less than 1 Meg of vRAM. The DAFB16pp table replaces
; the DAFB table when a DAFB3, running at 33 Mhz, is controlling an AC842A with at least 1 Meg of vRAM.
;
DAFB16bppTable ;
; Family Misc Modes: 2MB, 1MB vRam
;----------------------------------------------------------------------------------------------------
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_RGB2Pbx,sRsrc_Vid_DAFB_RGB2Pb,0 ; Vesuvio
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_FPb,sRsrc_Vid_DAFB_FPb,0 ; Mono Full-Page
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_GSx,sRsrc_Vid_DAFB_GSx,sRsrc_Vid_DAFB_GSz ; Rubik
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_2Pb,sRsrc_Vid_DAFB_2Pb,0 ; Two-Page
DC.B sRsrc_Vid_DAFB_NTSCconvSTx, \ ;
sRsrc_Vid_DAFB_NTSCconvFFx, \ ;
sRsrc_Vid_DAFB_NTSCSTbx, \ ;
sRsrc_Vid_DAFB_NTSCFFbx, \ ;
0, sRsrc_Vid_DAFB_NTSCSTbx,sRsrc_Vid_DAFB_NTSCSTax,0 ; NTSC
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_RGBFPbx,sRsrc_Vid_DAFB_RGBFPb,0 ; RGB Full-Page
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_HRbx,sRsrc_Vid_DAFB_HRax,0 ; High-Res RGB/Mono
;••• More configuration stuff here for extended-sense displays… •••
DC.B 0,0,0,0, 0, sRsrc_NeverMatch,sRsrc_NeverMatch,sRsrc_NeverMatch ; No-Connect
DC.B 0,0, \
sRsrc_Vid_DAFB_VGAbx, \
sRsrc_Vid_DAFB_SVGAbx, \
0, sRsrc_Vid_DAFB_VGAbx,sRsrc_Vid_DAFB_VGAax,0 ; VGA
DC.B sRsrc_Vid_DAFB_PALconvSTx, \ ;
sRsrc_Vid_DAFB_PALconvFFx, \ ;
sRsrc_Vid_DAFB_PALSTbx, \ ;
sRsrc_Vid_DAFB_PALFFbx, \ ;
0, sRsrc_Vid_DAFB_PALSTbx,sRsrc_Vid_DAFB_PALSTax,0 ; PAL
DC.B 0,0,0,0, 0, sRsrc_Vid_DAFB_LPbx,sRsrc_Vid_DAFB_LPax,0 ; Goldfish
Dc.b 0,0,0,0, 0, sRsrc_Vid_DAFB_19bx,sRsrc_Vid_DAFB_19b,0 ; 19"
Align 4
MiniGammaTable
; bR wR bG wG bB wB
;---------------------------------------------------------------------------------------------------- <4>
Dc.b $00,$FF,$00,$FF,$00,$FF,0,0 ; Vesuvio
Dc.b $00,$00,$00,$00,$00,$FF,0,0 ; Mono Full-Page
Dc.b $05,$FF,$05,$FF,$05,$FF,0,0 ; Rubik
Dc.b $00,$00,$00,$00,$00,$FF,0,0 ; Two-Page
Dc.b $00,$FF,$00,$FF,$00,$FF,0,0 ; NTSC
Dc.b $00,$FF,$00,$FF,$00,$FF,0,0 ; RGB Full-Page
Dc.b $00,$FF,$00,$FF,$00,$FF,0,0 ; High-Res RGB/Mono
Dc.b $00,$00,$00,$00,$00,$00,0,0 ; <No-Connect>
Dc.b $00,$FF,$00,$FF,$00,$FF,0,0 ; VGA
Dc.b $00,$FF,$00,$FF,$00,$FF,0,0 ; PAL
Dc.b $00,$FF,$00,$FF,$00,$FF,0,0 ; GoldFish
Dc.b $00,$FF,$00,$FF,$00,$FF,0,0 ; 19"
Dc.b $00,$00,$00,$FF,$00,$00,0,0 ; Radius MonoTPD
Align 4
ModeTable
; 2Meg,1Meg,512k
;----------------------------------------------------------------------------------------------------
Dc.b FourthVidMode,FourthVidMode,ThirdVidMode,0 ; Vesuvio
Dc.b FirstVidMode,FirstVidMode,FirstVidMode,0 ; Mono Full-Page
Dc.b FourthVidMode,FourthVidMode,FourthVidMode,0 ; Rubik
Dc.b FirstVidMode,FirstVidMode,FirstVidMode,0 ; Two-Page
Dc.b FourthVidMode,FourthVidMode,FourthVidMode,0 ; NTSC
Dc.b FourthVidMode,FourthVidMode,ThirdVidMode,0 ; RGB Full-Page
Dc.b FourthVidMode,FourthVidMode,FourthVidMode,0 ; High-Res RGB/Mono
Dc.b 0,0,0,0 ; <No-Connect>
Dc.b FourthVidMode,FourthVidMode,FourthVidMode,0 ; VGA
Dc.b FourthVidMode,FourthVidMode,FourthVidMode,0 ; PAL
Dc.b FourthVidMode,FourthVidMode,FourthVidMode,0 ; GoldFish
Dc.b FourthVidMode,FourthVidMode,ThirdVidMode,0 ; 19"
Align 4
DAFBPrelimInit
; Clock chip parms
DC.B $08,$0F,$00,$00,$0F,$01,$00,$00,$00,$01 ; Non-common 8531 parms.
DAFB8531Comm DC.B $05,$06,$04,$01,$00,$00 ; Common 8531 parms.
; Misc params
;
Dc.b $00,$00 ; MaxMode a,b
Dc.b $00,$00 ; Non-Wombat AMD TimingAdj Fudge
Dc.w $0000 ; Active Height
; Static DAFB params
;
Dc.w $0648,$0646,$0004,$0009,$0040,$0640,$0644 ; Static Swatch params.
; One bit mode parameters
;
DC.W $0080,$0606,$0030 ; DAFB parms (Note: ClkSel bit is off here.)
DC.W $012A,$00A5,$000C,$014B,$0017,$001A ; Dynamic Swatch parms
DC.W $0023,$003F,$013F,$014A,$0029 ;
DC.W $00C0 ; ACDC parms
Dc.w $0029,$003F,$013F ; AMD params
WDAFBPrelimInit
; Clock chip parms
;
DC.B $08,$0F,$00,$00,$0F,$01,$00,$00,$00,$01 ; 8531 chip parms (Not used here.)
Dc.w $3C04,$0040,$0400 ; 8534 chip parms.
; Misc params
;
Dc.b $00,$00 ; MaxMode a,b
Dc.b $00,$00 ; Non-Wombat AMD TimingAdj Fudge
Dc.w $0000 ; Active Height
; Static DAFB params
;
Dc.w $0648,$0646,$0004,$0009,$0040,$0640,$0644 ; Static Swatch params.
; One bit mode parameters
;
DC.W $0080,$0706,$0030 ; DAFB parms (Note: ClkSel bit is on here.)
DC.W $012A,$00A5,$000C,$014B,$0017,$001A ; Dynamic Swatch parms
DC.W $0023,$003F,$013F,$014A,$0029 ;
DC.W $00C0 ; ACDC parms
Dc.w $0029,$003F,$013F ; AMD params
ENDWITH
_EndsPrimaryInitRec
ENDP
END