mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
3134 lines
128 KiB
Plaintext
3134 lines
128 KiB
Plaintext
;
|
|
; File: InterruptHandlers.a
|
|
;
|
|
; Contains: This module contains the receivers for all 68000-family auto-vectored
|
|
; interrupts. It decodes the interrupt source and calls the associated
|
|
; interrupt handler. A PowerPC Macintosh may run this code in emulation.
|
|
;
|
|
; Written by: Bud Tribble
|
|
; Re-written by: Gary G. Davidian 5-Mar-89
|
|
;
|
|
; Copyright: © 1981-1994 by Apple Computer, Inc. All rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM63> 1/11/94 GS Enabled NMI in Grand Central on TNT.
|
|
; <SM61> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
|
; machines.
|
|
; <SM60> 11/19/93 chp Reflect macro API change in GrandCentralPriv, change some word
|
|
; branches to byte branches, and update SCSI IE primitives to work
|
|
; with both Grand Central SCSI buses. (see also: <SMG7-8>)
|
|
; <SM59> 11/10/93 fau Update from SuperMunggio <SMG2-9>. Also, addeb back KW's <SM56>
|
|
; checkin.
|
|
; <SMG9> 10/20/93 fau Enabled the PowerOff and One-secs interrupts for GrandCentral.
|
|
; <SMG8> 9/22/93 chp The Grand Central interrupt handler registration macros
|
|
; underwent an interface change.
|
|
; <SMG7> 9/13/93 chp Enable VIA interrupts after initializing the interrupt
|
|
; dispatcher, and enable only SCSI0 interrupts for the time being.
|
|
; <SMG3> 8/26/93 chp Use the provided interrupt dispatch table maintenance macros in
|
|
; within the Grand Central interrupt initialization postproc.
|
|
; <SMG2> 8/25/93 chp Introduce Grand Central support for TNT.
|
|
; <SM58> 11/10/93 rab Added semicolon to last checkin comment <MC5> so the build
|
|
; wouldn't barfÉ
|
|
; <SM57> 11/10/93 SAM Roll in <MC5> from mc900ftjesus.
|
|
; <MC5> 11/10/93 SAM Disable sound in/out DMA in AMICInitPostProc.
|
|
; <SM56> 11/9/93 KW added some eieioSTP macros. Only expands for CygnusX1 ROM
|
|
; <SM55> 10/29/93 pdw Moved intRegs and intRegsSize out of here and into
|
|
; SysPrivateEqu.a since SCSI Manager 4.3 is now using them.
|
|
; <SM54> 10/14/93 pdw Saving and restoring interrupt level around calls to 2nd-level
|
|
; interrupt handlers dispatched from AMIC DMA dispatch routine
|
|
; because somebody isn't restoring it themselves.
|
|
; <SM53> 9/25/93 SAM Changed the conditional around AMICIntTbl from hasAMIC to hasHMC
|
|
; because the only code the references it is in UniversalTables.a
|
|
; and that code is (rightly so) conitionalized with hasHMC.
|
|
; <SM52> 9/10/93 pdw Pulled the SCC Level 4 interrupt vectors and refcons out of the
|
|
; DMA Dispatch table (just like the maceVector).
|
|
; <SM51> 9/9/93 pdw Removed some leftover 24-bit support. Rearranged basic interrupt
|
|
; handling mechanism - no more jump islands, no more ServiceInt,
|
|
; now new FinishInt. Check it out.
|
|
; <SMG5> 9/1/93 chp When initializing PDM serial handlers, index into the table
|
|
; instead of hard-coding table offsets. When decoding serial
|
|
; interrupts, use a symbolic constant rather than a literal (per
|
|
; changes in DMADispGlobals).
|
|
; <SMG4> 8/30/93 chp Created a level 3 handler for PDM so MACE interrupts are
|
|
; processed symmetrically. Updated AMICInitPostProc to work with
|
|
; the slightly larger dispatch table.
|
|
; <SM49> 9/2/93 SKH StdVIA2DT always needs to be defined, because the universal code
|
|
; needs it.
|
|
; <SM48> 8/21/93 chp Reduced the PDMDMAHndlr instruction count by 30%.
|
|
; <SM47> 8/20/93 chp Clean up and somewhat reorganize the entire file. The 24/32 bit
|
|
; interrupt dispatcher paths are better integrated and the PSC
|
|
; interrupt dispatchers are now fully integrated into the same
|
|
; path. Bits and pieces from all over have been collected to
|
|
; reside closely with related functions. AMIC interrupt handlers
|
|
; have been slightly modified to use the standard install and
|
|
; dispatch mechanisms that everyone else uses. Some names changed
|
|
; for consistency and descriptiveness, particularly in the PSC
|
|
; code.
|
|
; <SM46> 8/2/93 pdw Changed first entry in SCSI speed table from 30MHz to 25MHz so
|
|
; that anything in the range 26 through 30 will use a value of 2
|
|
; instead of 3. This is in accordance with the timing provided by
|
|
; Jimmy.
|
|
; <SM45> 8/1/93 pdw Fixed Sam's 66/33-with-HDT-on-Eagle problem by changing the
|
|
; 33MHz entry in the SCSI handshaking table to 30, causing a 33 to
|
|
; use the value 2 instead of 3.
|
|
; <SM44> 8/1/93 pdw Fixed 50/50 AMIC/SCSI problem by avoiding the dangerous SCSI
|
|
; speed value of 3 (11 in 2 speed bits).
|
|
; <SM43> 7/19/93 pdw Added blocking of interrupts before testing DTskQHdr for
|
|
; presence of deferred tasks. Fixes a bug where you can drop to
|
|
; level 0 without executing deferred tasks.
|
|
; <SM42> 7/1/93 KW Roll in from LW. In PSCInitPostProc took out installation of
|
|
; muni nubus control int. handler. Also removed MuniVia2Int
|
|
; <SM41> 6/14/93 kc Roll in Ludwig.
|
|
; <SM40> 6/2/93 GMR Added separate interrupt table for PDM, so we can have our own
|
|
; Disable routine to turn off level 3 (Mace) interrupts. Also,
|
|
; change PDM's level 4 handler (DMA,SCC) to loop until all bits
|
|
; are clear, since the AMIC is set to interrupt on change only.
|
|
; <SM39> 5/25/93 SAM Added some Supports24Bit condos around ServiceIntMMU.
|
|
; <SM38> 5/24/93 joe PDM DMA int handler now calls ServiceIntMMU so deferred tasks
|
|
; will be run. Conditionalized 24-bit case out of ServiceIntMMU
|
|
; for PDM & Smurf.
|
|
; <SM37> 4/23/93 SAM Added a bunch of code to PDMDmaInstall. Each channel is reset
|
|
; at install timeand AMIC is now configured for the I/O bus speed
|
|
; of the machine we're on.
|
|
; <SM36> 4/22/93 CSS Changed emDMADispGlobs to emDMADispatchGlobals which matches
|
|
; Reality.
|
|
; <SM35> 4/11/93 chp Removed conditional assembly for Time Manager VBL emulation and
|
|
; instituted a runtime check in Enable60HzInts based on
|
|
; ProductInfo. Also rolled in various updates to the PSC interrupt
|
|
; handlers.
|
|
; <SM34> 4/5/93 RC Changed the DMA interrupts to Level 4 on PDM and added the SCC
|
|
; interrupt handleing to the DMA handler.
|
|
; <SM33> 4/2/93 GMR Added a couple of nop's to PDMDMAHndlr to synchronize I/O.
|
|
; <SM32> 4/1/93 GMR Moved PDM's DMA stuff from StartInit to here, where it belongs.
|
|
; <SM31> 2/25/93 RB Removed the call to WaitFloppyEject from PowerOff since this is
|
|
; now handled more elegantly in ShutDown.a. Renamed the
|
|
; WaitFloppyEject code to WaitAWhile and moved it into
|
|
; EgretPowerOff since it's still used there.
|
|
; <SM30> 1/20/93 PN Bring over the fix for PSCL5Interrupt from Ludwig where A4 value
|
|
; is trashed after 1st time through the loop.
|
|
; <SM29> 12/18/92 RB Swapped an entry on the port A interrupt handlers for the SCC in
|
|
; StdLvl12DT. This prevents the machines from freezing when the
|
|
; serial port is used.
|
|
; <SM28> 12/11/92 chp Optimized PSC interrupt dispatchers. Moved SCCA interrupt
|
|
; priority ahead of SCCB since this is the prioritization used by
|
|
; the SCC itself (see also SM10). Fixed a bug which most of the
|
|
; time prevented interrupt flags from being rechecked as intended
|
|
; (see also SM17).
|
|
; <SM27> 12/11/92 SWC Moved the rest of the Cyclone interrupt initialization stuff
|
|
; here from StartInit.a and added a general "post proc" routine to
|
|
; InitIntHandler to do any special-case initialization that can't
|
|
; be driven from just a table.
|
|
; <SM26> 12/1/92 EH Added interrupt table for Pratt.
|
|
; <SM25> 12/1/92 SWC Rewrote much of the file to do interrupt enable/disable and
|
|
; vector initialization based on tables attached to a machine's
|
|
; ProductInfo. This should make it much easier to follow what's
|
|
; going on. Added in build conditionals. Moved really old CPU
|
|
; support to the end of the file where it's conditionalized out
|
|
; with an "IF 0 THEN".
|
|
; <SM24> 11/20/92 fau Added a MUNI interrupt handler for Cyclone.
|
|
; <SM23> 11/16/92 rab Roll in Horror changes (see H7 comments below)
|
|
; <SM22> 11/4/92 fau Backed out change in <SM19> 'cause we found what the real
|
|
; culprit was (somebody writing to a ROM address that was at that
|
|
; table!)
|
|
; <SM21> 11/3/92 RB Do not "fall-into" ServiceIntMMU, since that defeats automatic
|
|
; vector patching schemes.
|
|
; <SM20> 11/3/92 SWC Changed ShutdownEqu.a->Shutdown.a.
|
|
; <SM19> 11/3/92 fau Moved the Via1Int/Via2Int Secondary interrupt dispatcher table
|
|
; further into the file to avoid an obscure data cache corruption
|
|
; problem (as far as we can tell) on a Q900/950. Changed the
|
|
; addressing mode to load values from this table to use 32-bit
|
|
; displacements.
|
|
; <SM18> 10/21/92 fau Changed all MMCExists to PSCExists.
|
|
; <SM17> 10/7/92 mal Changed Cyclone L3,4,5,6 interrupt dispatchers to check for a
|
|
; "later" interrupt.
|
|
; <SM16> 9/28/92 RB Fix PowerOff on Quadra 900 & 950 by updating the Egret check in
|
|
; the PowerOff trap.
|
|
; <SM15> 9/10/92 AEK Add support for 60.15 Hz pseudo-VBL interrupts (ala IIfx)
|
|
; Removed OSS 60Hz interrupt enable code (interrupt should never be enabled)
|
|
; Note: should be build-time selectable (currently set to non-HW vbl)
|
|
; <SM14> 8/26/92 kc Fix compiler warning.
|
|
; <SM13> 8/24/92 PN Take out checkEVT1 code
|
|
; <SM12> 8/17/92 CCH Changed ÒTestForÓ of OrwellExists to OrwellDecoder.
|
|
; <H7> 8/4/92 SWC Increased the floppy eject delay in PowerOff from 0.5 seconds to
|
|
; 1.5 seconds to support the slower drives used in the PowerBooks.
|
|
; With the shorter delay, the disk was ejected correctly, but the
|
|
; eject mechanism was left in an in-between state when the power
|
|
; goes off. This could potentially have reliability repercussions.
|
|
; <SM11> 6/30/92 kc Rename EclipseVia2SlotInt to DAFBVia2SlotInt. Move SlotInterrupt
|
|
; handlers from InterruptHandlers.a.
|
|
; <SM10> 6/22/92 mal Changed priority of PSCL4Interrupt to SCCB, SCCA, Sound, then
|
|
; DMA ints.
|
|
; <SM9> 6/21/92 PN Rollin PatchIIciROM.a and fix the through put problem on Apollo
|
|
; and TimLC
|
|
; <SM8> 6/21/92 RB Added temporary checks for the EVT1 Cyclone boxflag to handle
|
|
; EVT1 boards. The EVT1 support will be deleted later, after all
|
|
; systems have been upgraded to EVT2.
|
|
; <SM7> 6/20/92 mal (RB) Made ASC routines do nothing on Cyclone.
|
|
; <SM6> 5/28/92 RB When I rolled in Cyclone, I forgot to add one more patch rollin
|
|
; from Horror. So it is now in.
|
|
; <SM5> 5/24/92 RB Added PSC interrupt handlers from the Pandora file
|
|
; InterruptHandlersPatch.a PSCLxDispatch routines.
|
|
; <SM4> 5/24/92 RB Making Cyclone changes...Pandora history is below. Removed
|
|
; support for 4Square and cleaned up a little bit. Patches were
|
|
; rolled in inline.
|
|
; <SM3> 5/17/92 kc Include PowerPrivEqu.a and add "pmCommandRec."
|
|
; <P8> 4/24/92 KW (SWC,H6) Modified DebugUtil to use the new ADB/DebugUtil primitives.
|
|
; Moved EnableSCSIIntsPatch here from PwrControlsPatches.a since this
|
|
; is where it's used anyway.
|
|
; <P7> 2/19/92 chp (JC,H5) Add support for level 3 interrupt for Sonic on Sonora based
|
|
; machines. On Mac II class machines, level 3 interrupt was previously
|
|
; unused.
|
|
; <SM2> 2/11/92 RB Need to add code for debugger support on the Quadras. Also
|
|
; removed dead code that used to diferentiate Eclipse from the
|
|
; rest so it could enable SCSI using CA2 instead of CB2. Eclipse
|
|
; eventually changed so that CB2 is SCSI.
|
|
; <P6> 2/11/92 GS Add patch in Power Switch Int handler to enable Soft Power Off. Patch
|
|
; code (PowerSwitchIntPatch) is located in EgretPatchesToo.a.
|
|
; <P5> 2/7/92 mal Updated references to RBV VIA2 IER & IFR to PSC VIA2 IER & IFR offsets.
|
|
; <P4> 1/24/92 mal Added PSCIntInstall back in. Changed DisableIntSources to use correct
|
|
; VIA2 IER offset for Cyclone.
|
|
; <P3> 1/22/92 RMP (for mal) Commented PSCINTINSTALL out.
|
|
; <P2> 1/21/92 mal Added patches to support PSC interrupt dispatchers for levels 3,4,5,&6.
|
|
; <H4> 12/20/91 JC Use common Via2/RBV offset equates.
|
|
; <H3> 8/13/91 SWC Fixed the revision numbers in the comments to reflect the HORROR
|
|
; numbering scheme instead of my own.
|
|
; <H2> 8/8/91 SWC Patched EnableSCSIInts so that SCSI interrupts won't be enabled
|
|
; on DB-Lite.
|
|
; <18> 10/29/91 SAM Removed several branch to next instruction that resulted from
|
|
; the removal of conditionals in the previous rev.
|
|
; <17> 10/18/91 JSM Get rid of all the stupid conditionals. This turned up several
|
|
; instances of two RTS instructions in a row, but I left these
|
|
; alone to make comparing objects easier until we merge in new ROM
|
|
; sources.
|
|
; <16> 10/1/91 JSM DonÕt use hasADB conditional, all future ROMs will support ADB.
|
|
; <15> 8/30/91 JSM Cleanup header.
|
|
; <14> 6/12/91 LN removed #include 'HardwareEqu.a'
|
|
; <13> 9/14/90 MSH Power off feature changed on TIM, requiring a new call to the
|
|
; power manager.
|
|
; <12> 8/8/90 BG Changed some assembly-time checks to run-time for handling
|
|
; Eclipse and non-Eclipse VIA2 interrupts.
|
|
; <11> 6/18/90 CCH Changed onEclipse conditional to hasEclipseVIA2.
|
|
; <10> 4/5/90 HJR Fix HcMac build by exporting Poweroff to HcMac builds.
|
|
; <9> 3/29/90 MSH Move PowerOff call from PowerMgr to here.
|
|
; <8> 3/22/90 GA Removing the bsr to EgretShutdown. Now, this function is
|
|
; performed by the diagnostics calling EgretMgr.
|
|
; <7> 2/28/90 GA Modified the 1 sec interrupts enable for Egret and the System
|
|
; PowerOff support to conform with the new Egret Manager Parameter
|
|
; block model.
|
|
; <6> 2/21/90 CCH Added a missing endif.
|
|
; <5> 2/19/90 BG Modified the SlotMgr VIA2 interrupt handler installer to know
|
|
; the difference between a hasMac2Via2 and a hasEclipseVIA2. Also
|
|
; added hasEclipseVIA2 to the PowerOff handling code. Added code
|
|
; to handle both 4Square and Eclipse when installing and handling
|
|
; SWIMIOP interrupts.
|
|
; <4> 2/14/90 GA Added PowerOff support for Egret. It issues a Power off command
|
|
; to Egret to turn off Erickson...
|
|
; <3> 2/12/90 BG Added interrupt handling for Eclipse.
|
|
; <2> 1/11/90 CCH Adding include of ÒHardwarePrivateEqu.aÓ.
|
|
; <3.2> 11/28/89 SWC Removed OssADB interrupt handling code.
|
|
; <3.1> 11/19/89 GGD NEEDED FOR ZONE-5. Fixed the Level 1 OSS interrupt handler to
|
|
; check the OSS mask before calling the SWIM IOP interrupt handler
|
|
; to correct a bug that only occurs during a small window in
|
|
; StartInit when SWIM IOP interrupts are masked.
|
|
; <3.0> 11/15/89 GMR NEEDED FOR ZONE-5. Added routine to enable RPU interrupts
|
|
; through the OSS.
|
|
; <2.9> 10/28/89 GGD NEEDED FOR ZONE-5. Fixed bug in Level 2 OSS interrupt handler
|
|
; when SCSI or Sound interrupts were masked, other level 2
|
|
; interrupt handlers might not have gotten called.
|
|
; <2.8> 7/15/89 GGD Added alignment of all interrupt handler entry points for better
|
|
; cache/burst performance.
|
|
; <2.7> 7/12/89 GGD Added conditionals around the overpatch padding so that it can
|
|
; be easily located.
|
|
; <2.6> 6/23/89 GGD Added optimization when running a 32 bit OS, to not call
|
|
; SwapMMUMode in the Int handlers Changed DebugUtil keyboard
|
|
; polling for IOP ADB systems to always call the interrupt handler
|
|
; and not bother checking the interrupt status. This eliminates
|
|
; problems with hangs in MacsBug, which are really caused by
|
|
; MacsBug not calling the DebugUtil Enter function, but fixing it
|
|
; in ROM makes it more robust, and is ALOT EASIER THAN TRYING TO
|
|
; GET MacsBug TO CHANGE. Added some padding to allow expansion
|
|
; space for F19 overpatch. Needed for AURORA and F19 ROMS.
|
|
; <2.5> 6/10/89 GGD Added code review changes, deleted power off (level 6) handler
|
|
; for all machines except the Mac II, since only Mac II generates
|
|
; the interrupt, to prevent power off if spurious level 6 int
|
|
; occured.
|
|
; <2.4> 5/29/89 GGD Added runtime test to DebugUtil to check for the various forms
|
|
; of ADB.
|
|
; <2.3> 5/20/89 GGD Changed a few label names related to IOP interrupt processing.
|
|
; <2.2> 4/30/89 GGD Major source modifications to make it universal, added several
|
|
; new routines to enable/disable interrupt sources. Much of the
|
|
; new code is conditional, making this code even harder to read.
|
|
; <2.1> 4/19/89 GGD Changed the OSS level 2 int handler to check the mask regs for
|
|
; SCSI and ASC, and not call the handler if masked.
|
|
; <2.0> 4/16/89 GGD Implemented DebugUtil keyboard polling for all machines.
|
|
; <1.9> 4/13/89 GGD Changed OSS interrupt handlers to use same priority as the Mac
|
|
; II for compatibility. Updated to use new names for OSS interrupt
|
|
; flags from HardwareEqu. Changed to get Base addresses from
|
|
; lowmem, instead of using absolute addresses.
|
|
; <1.8> 4/7/89 MSH Removed HcSoundHack.
|
|
; <1.7> 3/6/89 GGD Completely re-written, restructured, and optimized. Old change
|
|
; histories kept for historical purposes only. restructured to
|
|
; eliminate need to branch back to DoneInts (rts instead), to
|
|
; localize mmu/pmgr/dtask code in one place. Added Deferred Task
|
|
; Mgr to onMacPP. Changed to use more feature based conditionals.
|
|
; Move the InitXVectTables routine from StartInit to here, and
|
|
; renamed it InitIntHandler. Moved OneSecInt handler to Clock.a
|
|
; Moved SlotVBLInt to VerticalRetraceMgr.a Moved 60Hz handler to
|
|
; VerticalRetraceMgr.a Moved Slot Interrupt handler to
|
|
; SlotInterrupts.a Always setup the level 1 dispatch table entry
|
|
; for the VBLint, even on OSS based systems. On OSS systems,
|
|
; dispatch to the VBLint handler through the dispatch table with
|
|
; A1 pointing to OSS60HzAck-VIFR, so that the standard VBLint
|
|
; handler can be used unmodified, and can be patched more easily.
|
|
; Eliminated unused include files. Changed RBV register usage now
|
|
; that equates are offsets from RBVBase, instead of being absolute
|
|
; addresses. Changed OSS int handlers to dispatch through the Via1
|
|
; or Via2 dispatch tables using entries that are in common with
|
|
; other systems. Added a hack for HcMac so that the ASC interrupt
|
|
; dispatch vector can be moved to be the same vector (in Via2DT)
|
|
; that the Mac II uses. Incorporated the change to PowerOff that
|
|
; was made for the SE/30, so that if the power doesn't go off, it
|
|
; will return from the trap. Greatly improved the performance of
|
|
; VIA interrupt handlers, removed the shifting/search loop, and
|
|
; replaced it with a fast table lookup.
|
|
; <1.6> 2/17/89 rwh don't pass VBase2 to SoundInt so it builds. SoundInt is an rts
|
|
; for now anyway...
|
|
; <1.5> 2/16/89 rwh added power off for OSS based machines.
|
|
; <1.4> 2/7/89 GGD Fixed DebugUtil to work on F19 too. Added MSH's Esprit changes
|
|
; (see him for info).
|
|
; <1.3> 12/14/88 MSH Removed idle code from level 1 dispatch, also fixed up speed
|
|
; code saving.
|
|
; <1.2> 12/13/88 rwh fix IopBypassInterrupt handling - better solution need IOPMgr
|
|
; work as well.
|
|
; <1.1> 11/10/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|
; <2.2> 11/6/88 GGD Ported to IoMac, added DebugUtil trap code for debugger support.
|
|
; <2.1> 11/1/88 MSH Rearranged the test order for doing deferred tasks.
|
|
; <2.0> 10/24/88 djw Added hasRBV conditional in SlotInt.
|
|
; <1.9> 10/5/88 CSL Added support for RBV.
|
|
; <1.8> 9/24/88 rwh add ExitInt label to level 5 dispatcher so MvMac build works.
|
|
; <¥1.7> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
|
; <1.6> 9/16/88 rwh Roll-in onMvMac changes, including ggd's improved deferred task
|
|
; dispatcher.
|
|
; <1.5> 9/9/88 MSH New version of speed saving and idle entry. Idle now is checked
|
|
; <1.4> 8/5/88 MSH Protecting savespeedo from being trashed by level 2 interrupt
|
|
; during level 1 interrupt servicing.
|
|
; <1.3> 7/8/88 MSH Added test for SCC enabled before reading interrupt register.
|
|
; <1.2> 4/21/88 djw Fixed hcMac bug in level 2 int hndlr for differentiating SCC and
|
|
; sound interrupts. Added restoring speedometer low mem.
|
|
; <1.1> 2/15/88 BBM modified for mpw 3.0 equates
|
|
; <1.0> 2/10/88 BBM Adding file for the first time into EASEÉ
|
|
; <Cxxx> 1/22/88 rwh Fixed Lvl5Int - needed to pop return addr off stack for bypass
|
|
; ints. <1.6>
|
|
; <Cggd> 12/18/87 ggd Changed polarity of slot interrupt bits for MvMac. <1.6>
|
|
; <C985> 12/17/87 MSH Added deferred task stuff for Laguna and clock speed support
|
|
; too.
|
|
; <C926> 11/3/87 rwh Roll in PB231: Fix deferred task dispatcher to dequeue task
|
|
; BEFORE calling it
|
|
; <C914> 10/29/87 rwh Port to Modern Victorian
|
|
; <C894> 9/30/87 MSH Port to HcMac (Laguna)
|
|
; <PB091> 4/20/87 RDC Rolled in patch from ROM78Fix for poweroff routine
|
|
; <C811> 2/13/87 RDC Add hook in deferred task routine for posterity
|
|
; <C803> 2/12/87 RDC Fix bug that allows deferred tasks to override VBL tasks
|
|
; <C705> 1/27/87 RDC Add fix to protect level 1 interrupts more globally from 32-bit
|
|
; mode. Deleted check in VBL handlers.
|
|
; <C694> 1/26/87 RDC Added various bug fixes
|
|
; <C686> 1/25/87 RDC Code review cleanup
|
|
; <C582> 1/2/87 RDC Remove MMU mode swap when dispatching to slot interrupt
|
|
; routines, add misc cleanup
|
|
; <C556> 12/19/86 FJL Changed NumSlots to sNumSlots for GWN.
|
|
; <C334> 12/9/86 JSP Added testing and use of MMU mode swapping to levels 1,2, and 4.
|
|
; <C409> 12/7/86 RDC Added deferred task support, cleaned up comments
|
|
; <C400> 11/11/86 RDC Another bug fix in interrupt handler for slot priority
|
|
; <C390> 11/10/86 RDC Fixed bug in interrupt handler for slot priority
|
|
; <A327> 11/2/86 RDC Finally added the copyright notice!
|
|
; <A261> 10/24/86 CSL Took out one autopoll per VBL for mouse data update.
|
|
; <C243> 10/18/86 RDC Added fix to SlotVBLInt to leave interrupts disabled for now
|
|
; <C166> 10/13/86 RDC Added use of slot priority table in Numac slot interrupt handler
|
|
; Changed slot int handling to use low mem ptr to int queue table
|
|
; <C147> 10/13/86 RDC Added changes for separation of VBL handling for NuMac since VBL
|
|
; tasks can now be assigned to a specific slot. Increased poweroff
|
|
; delay to two seconds for disk eject. Removed call to keyboard
|
|
; task for new systems.
|
|
; <C199> 10/3/86 CSL Set one autopoll per VBL for mouse data update. Fixed in Kbd.a
|
|
; and Crsrcore.a. Changed include files
|
|
; <C121> 8/20/86 RDC Added change to NuMac slot interrupt handler to fix problem of
|
|
; missing slot interrupts
|
|
; <C120> 8/19/86 RDC Added reset of NuMac VIA int flag bit for slots in the slot
|
|
; interrupt handler so cards don't have to do it.
|
|
; <C112> 8/7/86 RDC Added comment changes for new NuMac hardware (VIA2 interrupt
|
|
; changes)
|
|
; <C101> 8/2/86 RDC Added fix for handling multiple slot interrupts
|
|
; <C84> 8/1/86 WRL Skip jCrsrTask in VBL handler if it's NIL.
|
|
; <C92> 7/29/86 RDC deleted video interrupt handler - now on video cards
|
|
; <C88> 7/28/86 RDC Added changes for handling NuMac slot interrupts.
|
|
; <C68> 7/17/86 RDC Increased poweroff delay loop to one sec to allow time for disk
|
|
; eject; changed routine name to Poweroff for trap use
|
|
; <C51> 6/24/86 RDC Added debounce loop to NuMac poweroff int handler
|
|
; <C48> 6/17/86 RDC Fixed bug in NuMac poweroff int handler
|
|
; <C42> 6/11/86 RDC Added interrupt handler for NuMac poweroff interrupt
|
|
; <C28> 5/30/86 CSL Added changes for Aladdin, and Aladdin Front desk bus support.
|
|
; <C9> 5/21/86 RDC Fixed slot interrupt dispatcher to check for interrupts from all
|
|
; slots before exiting
|
|
; <C1> 4/15/86 RDC Added changes for 020 Reno project (NuMac) - removed call to
|
|
; cursor task (called by slot interrupt handler) - Added interrupt
|
|
; handler for second VIA and for slots - Added video card
|
|
; interrupt handler
|
|
; 2/19/86 BBM Made some modifications to work under MPW
|
|
; 1/15/86 ELR Removed SCSI interrupt handler, in keeping with the fact that
|
|
; SCSI interrupts were removed.
|
|
; 9/25/85 LAK Finally fixed outstanding bug in SCC ext/sts dispatch: we 'and'
|
|
; the status with RR15 value so we just consider bits which are
|
|
; enabled to cause interrupts. Without this fix, an external clock
|
|
; can cause us to ignore half of our mouse interrupts (this is
|
|
; also seen when connected to AppleTalk on a very busy network).
|
|
; 9/6/85 ELR Added code to field SCSI chip interrupts on LVL1 int vector.
|
|
; (OnMac)
|
|
; 7/24/85 RDC Added spearate include statement for HWequ file (no longer in
|
|
; systlqk.sym)
|
|
; 7/23/85 RDC Added mouse interrupt routines from CrsrCore Added changes for
|
|
; MidMac - removed mouse int routines (handled by Front Desk Bus)
|
|
; - added call of keyboard task every VBL int
|
|
; 1/29/85 LAK Put RAM patch code in (one sec int support for alarm).
|
|
; 1/23/85 LAK Adapted for new equate files.
|
|
; 8/19/83 LAK StkLowPt now managed by VBL handler; calls SysError in case of
|
|
; stack crashing into heap.
|
|
; 8/17/83 LAK Now calls cursor task via a lowmem vector.
|
|
; 8/6/83 LAK Increments random number seed when mouse button changes. Saved
|
|
; some code by pointing Lvl1RTS and Lvl2RTS at an RTS and Spurious
|
|
; at an RTE.
|
|
; 6/10/83 LAK Changed level 2 interrupt handler (see comments there).
|
|
; 6/10/83 LAK Added delay between SCC write and read (was only 6 pclks + 50ns)
|
|
; by loading 'and' mask before reading SCC interrupt vector.
|
|
; Changed ext int handler to ignore mouse movements when any other
|
|
; external condition has happened.
|
|
; 2/16/83 LAK VBL interrupt dispatcher calls keyboard manager thru KybdTask
|
|
; vector.
|
|
; 11/15/82 LAK no more deferred task manager
|
|
; 11/5/82 LAK only high bit of MBState set now (just a little bit nicer)
|
|
; 8/26/82 LAK updated for 512-dot machine
|
|
; 8/15/82 LAK A0-A1 point to appropriate port; save more registers; put in
|
|
; secondary ext/sts dispatch routine
|
|
; 8/10/82 LAK brought deferred task handler here from Dispatch
|
|
; 6/4/82 LAK changed VBL handler to call keyboard task only every 32
|
|
; interrupts.
|
|
; 5/2/82 LAK adapted to the SCC hardware; uses SCC interrupt vector to decide
|
|
; which service routine to go to
|
|
; 4/29/82 LAK adapted to the SCC hardware, included mouse button handler from
|
|
; KBD.
|
|
; 10/5/81 bmw made it check deferred tasks on exit
|
|
; 5/13/81 AJH added Level 1 Interrupt Handler
|
|
;
|
|
; To Do: There is a potential problem when calling VRemove while the Vertical Retrace
|
|
; Manager is executing. This is only a problem for interrupt routines that call
|
|
; VRemove, so it can be avoided by placing the restriction that such routines
|
|
; may remove a VBL task only by letting its count expire.
|
|
;
|
|
;-----------------------------------------------------------------------------------------
|
|
|
|
print push,off
|
|
|
|
load 'StandardEqu.d'
|
|
include 'HardwarePrivateEqu.a'
|
|
include 'SysPrivateEqu.a'
|
|
include 'UniversalEqu.a'
|
|
include 'IOPrimitiveEqu.a'
|
|
include 'ShutDown.a'
|
|
|
|
IF hasPwrControls THEN
|
|
include 'PowerPrivEqu.a'
|
|
ENDIF
|
|
|
|
IF hasEgret THEN
|
|
include 'EgretEqu.a'
|
|
ENDIF
|
|
|
|
IF hasPSC THEN
|
|
include 'PSCEqu.a'
|
|
ENDIF
|
|
|
|
IF hasAMIC THEN
|
|
include 'AMICEqu.a'
|
|
ENDIF
|
|
|
|
IF hasGrandCentral THEN
|
|
include 'GrandCentralPriv.a'
|
|
ENDIF
|
|
|
|
print pop
|
|
print nomdir
|
|
|
|
machine mc68020
|
|
|
|
|
|
|
|
; interrupt setup primitives record
|
|
|
|
InterruptPrims RECORD {intInitPostProc},INCREMENT
|
|
flags DS.W 1 ; miscellaneous flags
|
|
count DS.W 1 ; number of entries in the table
|
|
|
|
intInitPostProc DS.L 1 ; post initialization dynamic setup
|
|
intDisableInts DS.L 1 ; disable all interrupt sources
|
|
intEnableOneSec DS.L 1 ; enable one second interrupts
|
|
intEnableSlots DS.L 1 ; enable slot interrupts
|
|
intEnableSound DS.L 1 ; enable sound interrupts
|
|
intDisableSound DS.L 1 ; disable sound interrupts
|
|
intClearSound DS.L 1 ; clear sound interrupts
|
|
intEnableSCSI DS.L 1 ; enable SCSI interrupts
|
|
intDisableSCSI DS.L 1 ; disable SCSI interrupts
|
|
intClearSCSIInt DS.L 1 ; clear SCSI interrupts
|
|
intPowerOffProc DS.L 1 ; custom power off code
|
|
|
|
intFirstVectTbl DS.L 1 ; first vectors table (end with a zero)
|
|
ENDR
|
|
|
|
; rename a few historical equates for clarity
|
|
|
|
Via1DT equ Lvl1DT ; dispatch table for VIA1 interrupts
|
|
SccDT equ Lvl2DT ; dispatch table for SCC interrupts
|
|
|
|
; define equates for common VIA dispatch table entries
|
|
|
|
jOneSecInt equ Via1DT+4*ifCA2 ; valid on all machines
|
|
jVBLInt equ Via1DT+4*ifCA1 ; valid on all machines
|
|
jKbdAdbInt equ Via1DT+4*ifSR ; not valid when IopADB or PwrMgrADB
|
|
|
|
jSlotInt equ Via2DT+4*ifCA1 ; valid when hasSlotMgr
|
|
jASCInt equ Via2DT+4*ifCB1 ; valid when hasASC
|
|
jSCSIIrqInt equ Via2DT+4*ifCB2 ; valid when has something VIA2-like
|
|
|
|
|
|
|
|
IntHnd proc export
|
|
|
|
import OneSecInt, VBLInt, IOPInterrupt
|
|
|
|
WITH ProductInfo, InterruptPrims
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: DisableIntSources
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: disables the external interrupt sources to prevent processor interrupts from occurring
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export DisableIntSources
|
|
DisableIntSources
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intDisableInts(A0),A0 ; and finally to the routine to disable interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Enable60HzInts
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: D0/A0-A1
|
|
;
|
|
; Function: enables the 60Hz interrupt source, so that when the processor interrupt
|
|
; mask is low enough, the interrupts will be generated
|
|
;
|
|
; 60Hz interrupts are generated either by VIA hardware or by a Time Manager
|
|
; task. The proper method is indicated in ProductInfo.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export Enable60HzInts
|
|
Enable60HzInts
|
|
|
|
TestFor SoftVBL
|
|
beq.b @VIAVBL
|
|
|
|
@TMVBL
|
|
import PseudoVBLInt
|
|
|
|
moveq.l #tmXQSize, d0 ; allocate a block in the system heap
|
|
_NewPtr ,SYS,CLEAR ; to hold the Time Manager task structure
|
|
lea PseudoVBLInt, a1
|
|
move.l a1, tmAddr(a0)
|
|
move.l #'eada', (a0) ; identify queue type to VM
|
|
_InsXTime
|
|
move.l #-16626, d0
|
|
move.l jPrimeTime, a1
|
|
jmp (a1)
|
|
|
|
@VIAVBL
|
|
movea.l VIA,a0 ; it is a VIA1 interrupt source
|
|
eieioSTP
|
|
move.b #(1<<ifIRQ)|(1<<ifCA1),vIER(a0) ; enable the CA1 interrupt
|
|
eieioSTP
|
|
rts
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: EnableOneSecInts
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: enables the one second interrupt source, so that when the processor
|
|
; interrupt mask is low enough, the interrupts will be generated
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export EnableOneSecInts
|
|
EnableOneSecInts
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intEnableOneSec(A0),A0 ; and finally to the routine to enable one second interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: EnableSlotInts
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: enables the NuBus slot interrupt source, so that when the processor
|
|
; interrupt mask is low enough, the interrupts will be generated
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export EnableSlotInts
|
|
EnableSlotInts
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intEnableSlots(A0),A0 ; and finally to the routine to enable slot interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: EnableSoundInts
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: enables the sound interrupt source, so that when the processor
|
|
; interrupt mask is low enough, the interrupts will be generated
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export EnableSoundInts
|
|
EnableSoundInts
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intEnableSound(A0),A0 ; and finally to the routine to enable sound interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: DisableSoundInts
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: disables the sound interrupt source, so that processor
|
|
; interrupts will not be generated
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export DisableSoundInts
|
|
DisableSoundInts
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intDisableSound(A0),A0 ; and finally to the routine to disable sound interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: ClearSoundInt
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: Disables the sound interrupt source, so that processor interrupts will
|
|
; not be acknowledged. Note that this only clears the interrupt at the
|
|
; secondary source (VIA/RBV/...) and it is expected that the caller will
|
|
; clear it at the sound chip.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export ClearSoundInt
|
|
ClearSoundInt
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intClearSound(A0),A0 ; and finally to the routine to clear sound interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: EnableSCSIInts
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: enables the SCSI interrupt source, so that when the processor
|
|
; interrupt mask is low enough, the interrupts will be generated
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export EnableSCSIInts
|
|
EnableSCSIInts
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intEnableSCSI(A0),A0 ; and finally to the routine to enable SCSI interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: DisableSCSIInts
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: disables the SCSI interrupt source, so that processor
|
|
; interrupts will not be generated
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export DisableSCSIInts
|
|
DisableSCSIInts
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intDisableSCSI(A0),A0 ; and finally to the routine to disable SCSI interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: ClearSCSIInt
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: Disables the SCSI interrupt source, so that processor interrupts will
|
|
; not be acknowledged. Note that this only clears the interrupt at the
|
|
; secondary source (VIA/RBV/...) and it is expected that the caller will
|
|
; clear it at the SCSI chip.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export ClearSCSIInt
|
|
ClearSCSIInt
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intClearSCSIInt(A0),A0 ; and finally to the routine to clear SCSI interrupts
|
|
JMP (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: PowerOff (trap $A05B)
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: D0 - result code (always zero)
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: This routine tries to turn off the power to the computer (if it's possible
|
|
; to do that). If power can't be turned off by software, it'll just return
|
|
; and the ShutDown software can put up a dialog instead.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export PowerOff
|
|
PowerOff
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A0),A0 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intPowerOffProc(A0),A0 ; and finally to the routine to power off the computer
|
|
JSR (A0) ; call it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: DebugUtil (trap $A08D)
|
|
;
|
|
; Inputs: D0 - selector
|
|
; 0 - return highest function number supported
|
|
; 1 - entering debugger (for debugger to inform the system)
|
|
; 2 - exiting debugger (for debugger to inform the system)
|
|
; 3 - run keyboard polling code without interrupts
|
|
;
|
|
; Outputs: D0 - result (dependent on selector)
|
|
;
|
|
; Trashes: none (A0-A2/D1-D2 are saved by OS trap dispatcher)
|
|
;
|
|
; Function: performs hardware dependent functions for the debugger, so that each time
|
|
; a new hardware design comes out we don't need a new debugger
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export DebugUtil
|
|
DebugUtil
|
|
lea @table,a0 ; point to the decoding table
|
|
cmp.l (a0)+,d0 ; range check the selector
|
|
bhi.s @tooBig ; if out of range
|
|
add.w d0,d0 ; table entries are 2 bytes each
|
|
adda.w (a0,d0.w),a0 ; point to the procedure
|
|
jmp (a0) ; execute the routine
|
|
@tooBig moveq.l #paramErr,d0 ; param error if out of range
|
|
rts ; all done
|
|
|
|
ALIGN 4
|
|
@table dc.l (@last-@first)/2-1 ; highest function number supported
|
|
@first
|
|
dc.w @getMax-@first ; 0 - return highest function number supported
|
|
dc.w DebugEnter-@first ; 1 - entering debugger
|
|
dc.w DebugExit-@first ; 2 - exiting debugger
|
|
dc.w DebugPoll-@first ; 3 - run keyboard polling code without interrupts
|
|
@last
|
|
|
|
@getMax move.l @table,d0 ; get the max
|
|
rts ; return it in D0
|
|
|
|
|
|
DebugEnter MOVEQ #4*adbDebugEnter,D0 ; table index for entry routine
|
|
BRA.S DebugUtilDispatch
|
|
|
|
DebugExit MOVEQ #4*adbDebugExit,D0 ; table index for exit routine
|
|
BRA.S DebugUtilDispatch
|
|
|
|
DebugPoll MOVEQ #4*adbDebugPoll,D0 ; table index for polling routine
|
|
* BRA.S DebugUtilDispatch
|
|
|
|
DebugUtilDispatch
|
|
MOVEM.L D1-D3/A0-A3,-(SP)
|
|
MOVEA.L UnivInfoPtr,A0 ; point to the ProductInfo table
|
|
ADDA.L ProductInfo.ADBDebugUtilPtr(A0),A0 ; and get the address of its ADB table
|
|
MOVE.L 0(A0,D0),D0 ; get the offset to the specified routine
|
|
BEQ.S @NoProc ; -> this function is not supported
|
|
ADDA.L D0,A0 ; calculate the routine's address
|
|
JSR (A0) ; and call it
|
|
@NoProc MOVEM.L (SP)+,D1-D3/A0-A3
|
|
MOVEQ #noErr,D0 ; always return with success
|
|
RTS
|
|
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Interrupt Primitive Routines
|
|
;
|
|
; Function: Implement hardware dependent interrupt enable functions underlying
|
|
; the abstract entry points above.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
IF hasMac2VIA2 | hasRBV | hasEclipseVIA2 THEN
|
|
|
|
; - - - - - VIA/RBV primitives - - - - -
|
|
|
|
VIADisableIntSources
|
|
movea.l VIA,a0 ; disable all interrupts in VIA1
|
|
eieioSTP
|
|
move.b #$7F,vIER(a0)
|
|
movea.l VIA2RBV,a0
|
|
eieioSTP
|
|
move.b #$7F,Rv2IER(a0) ; and in VIA2
|
|
eieioSTP
|
|
rts
|
|
|
|
VIAEnableOneSecInts ; enable one second interrupts by setting CA2
|
|
movea.l VIA,a0 ; in the VIA1 enables register
|
|
eieioSTP
|
|
move.b #(1<<ifIRQ)|(1<<ifCA2),vIER(a0)
|
|
eieioSTP
|
|
rts
|
|
|
|
VIAEnableSlotInts ; enable slot interrupts by setting CA1
|
|
movea.l VIA2RBV,a0 ; in the VIA2 enables register
|
|
eieioSTP
|
|
move.b #(1<<ifIRQ)|(1<<ifCA1),Rv2IER(a0)
|
|
eieioSTP
|
|
rts
|
|
|
|
VIAEnableSoundInts ; enable sound interrupts by setting CB1
|
|
movea.l VIA2RBV,a0 ; in the VIA2 enables register
|
|
eieioSTP
|
|
move.b #(1<<ifIRQ)|(1<<ifCB1),Rv2IER(a0)
|
|
eieioSTP
|
|
rts
|
|
|
|
VIADisableSoundInts ; disable sound interrupts by clearing CB1
|
|
movea.l VIA2RBV,a0 ; in the VIA2 enables register
|
|
eieioSTP
|
|
move.b #(0<<ifIRQ)|(1<<ifCB1),Rv2IER(a0)
|
|
eieioSTP
|
|
rts
|
|
|
|
VIAClearSoundInts ; clear a sound interrupt by setting CB1
|
|
movea.l VIA2RBV,a0 ; in the VIA2 flags register
|
|
eieioSTP
|
|
move.b #(1<<ifIRQ)|(1<<ifCB1),Rv2IFR(a0)
|
|
eieioSTP
|
|
rts
|
|
|
|
VIAEnableSCSIInts ; enable SCSI IRQ by setting CB2
|
|
movea.l VIA2RBV,a0 ; in the VIA2 enables register
|
|
eieioSTP
|
|
move.b #(1<<ifIRQ)|(1<<ifCB2),Rv2IER(a0)
|
|
eieioSTP
|
|
rts
|
|
|
|
VIADisableSCSIInts ; disable SCSI IRQ by clearing CB2
|
|
movea.l VIA2RBV,a0 ; in the VIA2 enables register
|
|
eieioSTP
|
|
move.b #(0<<ifIRQ)|(1<<ifCB2),Rv2IER(a0)
|
|
eieioSTP
|
|
rts
|
|
|
|
VIAClearSCSIInts ; clear SCSI IRQ by setting CB2
|
|
movea.l VIA2RBV,a0 ; in the VIA2 flags register
|
|
eieioSTP
|
|
move.b #(1<<ifIRQ)|(1<<ifCB2),Rv2IFR(a0)
|
|
eieioSTP
|
|
rts
|
|
|
|
VIAPowerOff movea.l VIA2RBV,A0
|
|
moveq.l #v2PowerOff,d0 ; get power off bit number
|
|
eieioSTP
|
|
bset.b d0,vDirB++RvDataB(a0) ; make the VIA/RBV bit an output
|
|
eieioSTP
|
|
bclr.b d0,vBufB++RvDataB(A0) ; and clear it to turn off the power
|
|
eieioSTP
|
|
rts
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
IF hasPwrControls THEN
|
|
|
|
; - - - - - Power Manager primitives - - - - -
|
|
|
|
WITH pmCommandRec
|
|
IMPORT StartBoot
|
|
|
|
; power off the computer using the PMGR
|
|
|
|
PMgrPowerOff
|
|
IF isUniversal THEN
|
|
TestFor hwCbPwrMgr
|
|
beq.s PmgrOffDone
|
|
ENDIF
|
|
|
|
CLR.L -(SP) ; pmRBuffer = nil
|
|
CLR.L -(SP) ; pmRBuffer = nil
|
|
CLR.W -(SP) ; pmLength = 0
|
|
MOVE.W #PmgrADBoff,-(SP) ; pmCommand = turn ADB autopoll off
|
|
MOVE.L SP,A0 ; point to the parameter block
|
|
_PmgrOp
|
|
LEA pmRBuffer+4(SP),SP ; clean up the stack
|
|
|
|
_HideCursor
|
|
CLR.L WarmStart ; be sure to do startup testing
|
|
|
|
; If we have the new PMGR then this command will work. If not then the call will
|
|
; fail and we will do it the old fashioned way.
|
|
|
|
PEA 'MATT' ; shutdown signature <H4>
|
|
MOVE.L SP,-(SP) ; pmRBuffer (not used) <H4>
|
|
MOVE.L (SP),-(SP) ; pmSBuffer (the sleep signature) <H4>
|
|
MOVE.W #4,-(SP) ; pmLength = 4 <H4>
|
|
MOVE.W #PmgrPWRoff,-(SP) ; pmCommand = power off <H4>
|
|
MOVE.L SP,A0 ; point to the parameter block <H4>
|
|
_PmgrOp ; power off using the PMGR <H4>
|
|
LEA pmRBuffer+4+4(SP),SP; clean up the stack <H4>
|
|
BNE.S @callSleep ; -> the call failed, so we have an old PMGR <H4>
|
|
|
|
BRA.S * ; Let the cyanide take affect
|
|
|
|
@callsleep MOVE.W #SleepNow,D0 ; Set it to sleep
|
|
_Sleep
|
|
BigJSR StartBoot,A0 ; Reboot the guy.
|
|
|
|
PmgrOffDone
|
|
RTS
|
|
ENDWITH ; {pmCommandRec}
|
|
ENDIF ; {hasPwrControls}
|
|
|
|
|
|
|
|
IF hasIopSwim THEN
|
|
|
|
; - - - - - SWIM IOP primitives - - - - -
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: EnableSwimIOPInts
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: A0
|
|
;
|
|
; Function: enables the SWIM IOP interrupt source, so that when the processor
|
|
; interrupt mask is low enough, the interrupts will be generated
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
export EnableSwimIOPInts
|
|
EnableSwimIOPInts
|
|
|
|
IF hasOSS THEN
|
|
TestFor OSSExists ; see if we really have an OSS
|
|
beq.s @notOSS ; if not, use the VIA2/RBV
|
|
movea.l OSS,a0 ; get OSS base
|
|
eieioSTP
|
|
move.b #MskIOP1,OSSMskPSwm(a0) ; enable the SWIM IOP interrupt mask
|
|
eieioSTP
|
|
rts
|
|
@notOss
|
|
ENDIF ; {hasOSS}
|
|
|
|
movea.l VIA2RBV,a0 ; Get base address of VIA2/RBV
|
|
eieioSTP
|
|
move.b #(1<<ifIRQ)|(1<<ifCA2),Rv2IER(a0) ; SWIM IOP interrupt is CA2
|
|
eieioSTP
|
|
rts
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Secondary Dispatch routines for IOP 1 interrupts
|
|
;
|
|
; On Entry: A1.L = VIA2 base address (if hasMac2Via2 only)
|
|
; D0-D3/A0-A3 have been saved
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
align alignment ; align on cache line boundary
|
|
SwimIopIntVIA
|
|
eieioSTP
|
|
move.b #1<<ifCA2,VIFR(A1) ; reset VIA2 int. flag
|
|
eieioSTP
|
|
|
|
SwimIopInt moveq.l #1,d0 ; Swim IOP is IOP number 1
|
|
eieioSTP
|
|
jmp IOPInterrupt ; handle the interrupt and return
|
|
eieioSTP
|
|
|
|
ENDIF ; {hasIopSwim}
|
|
|
|
|
|
|
|
IF hasEgret THEN
|
|
|
|
; - - - - - Egret primitives - - - - -
|
|
|
|
WITH EgretPB
|
|
|
|
; This routine will enable the one second IRQ in Egret. The Mode will be 3 which forces
|
|
; tick packets first and if Egret cannot send the packet then it will send a Read Real
|
|
; Time Clock command. This command returns the full 32 bit time setting back to the system.
|
|
|
|
EgretEnableOneSecInts
|
|
lea -EgretPBSize(sp),sp ; build a record on the stack
|
|
move.l sp,a0 ; point to the start of the record
|
|
move.b #pseudopkt,pbCmdType(a0) ; we want a pseudo request
|
|
move.b #wr1secmode,pbCmd(a0) ; Start 1 sec irq Mode 3
|
|
move.b #3,pbParam(a0)
|
|
clr.l pbCompletion(a0) ; nil completion vector pointer
|
|
_EgretDispatch ; issue the call Egret Manager
|
|
lea EgretPBSize(sp),sp ; Discard the record
|
|
rts
|
|
|
|
; This routine will issue a Power off command to Egret. If the call succeeds, the power
|
|
; supply will be turned off and the system will sleep. If the poweroff command cannot turn
|
|
; off the supply then the call will return and the system will display a restart dialog.
|
|
|
|
EXPORT EgretPowerOff
|
|
EgretPowerOff
|
|
lea -EgretPBSize(sp),sp ; build a record on the stack
|
|
move.l sp,a0 ; point to the start of the record
|
|
move.b #pseudopkt,pbCmdType(a0) ; we want a pseudo request
|
|
move.b #pwrdown,pbCmd(a0) ; PowerDown Command
|
|
move.b #0,pbParam(a0) ; A zero stops autopoll
|
|
clr.l pbCompletion(a0) ; nil completion vector pointer
|
|
_EgretDispatch ; issue the call Egret Manager
|
|
lea EgretPBSize(sp),sp ; clean up the stack
|
|
bra WaitAWhile ; if it returns then Power Off failed
|
|
|
|
; Wait an additional 1.5 seconds for for power to turn off.
|
|
; If it doesn't we just return from the _PowerOff trap.
|
|
|
|
WaitAWhile
|
|
move.l #(-1500)<<16,d0 ; outer loop count 500*1ms
|
|
@outer move.w TimeDBRA,d0 ; inner loop count 1ms
|
|
@inner dbra d0,@inner ; wait 1ms
|
|
addq.l #1,d0 ; increment outer loop counter
|
|
bne.s @outer ; wait 500*1ms
|
|
rts ; the long wait is over
|
|
|
|
ENDWITH ; {EgretPB}
|
|
ENDIF ; {hasEgret}
|
|
|
|
|
|
|
|
IF hasPSC THEN
|
|
|
|
; - - - - - PSC primitives - - - - -
|
|
|
|
PSCInitPostProc
|
|
TestFor MUNIExists ; Install MUNI Interrupt handler in VIA2 Dipatch Table
|
|
beq.s @NoMuni ; No Muni
|
|
Move.l #1, MUNIBase+MUNI_IntCntrl ; disable MUNI interrupts (no handler)
|
|
@NoMuni
|
|
|
|
WITH ExpandMemRec, PSC_INT_TBL
|
|
|
|
move.l #PSC_INT_TBL_SZ,D0 ; 8 bytes needed per table entry
|
|
_NewPtr ,SYS,CLEAR ; allocate it and zero out the memory
|
|
|
|
move.l a0,([ExpandMem],emDMADispatchGlobals) ; and save it
|
|
beq.b @noPSC ; abort further installation if Ptr is nil
|
|
|
|
; For compatibility with third-party serial driver replacements like MIDI, MacRecorder, etc.
|
|
; The old SCC interrupt handler code is installed into the PSC interrupt table and SCC
|
|
; interrupts are enabled through the PSC. This should make the PSC implementation look just
|
|
; like the traditional implementation.
|
|
;
|
|
lea SccDecode,a1 ; default SCC interrupt handler
|
|
move.l a1,L4SCCAhndlr(a0) ; services port A
|
|
move.l a1,L4SCCBhndlr(a0) ; services port B
|
|
|
|
movea.l UnivInfoPtr,a0
|
|
adda.l ProductInfo.DecoderInfoPtr(a0),a0
|
|
movea.l DecoderInfo.PSCAddr(a0),a0
|
|
move.b #1 << L4B7 | 1 << L4SCCB | 1 << L4SCCA, L4IER(a0)
|
|
@noPSC
|
|
ENDWITH ; {ExpandMemRec, PSC_INT_TBL}
|
|
RTS
|
|
|
|
PSCDisableIntSources
|
|
movea.l VIA,a0 ; VIA1 base address
|
|
move.b #$7F,vIER(a0) ; disable all interrupts
|
|
movea.l VIA2,a0 ; VIA2 base address
|
|
Move.b #$6F,vIER(a0) ; disable all interrupts
|
|
rts ; continue with our program
|
|
|
|
PSCEnableSlotInts
|
|
movea.l VIA2,a0 ; VIA2 base address
|
|
move.b #(1<<ifIRQ)|(1<<ifCA1),\ ; any slot interrupt is CA1
|
|
vIER(a0) ; enable the CA1 interrupt
|
|
rts
|
|
|
|
PSCEnableSCSIInts
|
|
movea.l VIA2,a0 ; VIA2 base address
|
|
Move.b #(1<<ifIRQ)|(1<<ifCB2),\ ; SCSI IRQ interrupt is CB2
|
|
vIER(a0) ; enable the SCSI interrupt
|
|
rts ; were are out of here...
|
|
|
|
PSCDisableSCSIInts
|
|
movea.l VIA2,a0 ; VIA2 base address
|
|
Move.b #(0<<ifIRQ)|(1<<ifCB2),\ ; SCSI IRQ interrupt is CB2
|
|
vIER(a0) ; enable the SCSI interrupt
|
|
rts ; were are out of here...
|
|
|
|
ENDIF ; {hasPSC}
|
|
|
|
|
|
|
|
IF hasAMIC THEN
|
|
|
|
; - - - - - AMIC primitives - - - - -
|
|
|
|
;________________________________________________________________________________________
|
|
;
|
|
; Routine: AMICInitPostProc
|
|
;
|
|
; Inputs: none
|
|
; Outputs: none
|
|
; Trashes: D0, A0
|
|
;
|
|
; Function: Sets up DMA base addresses and installs IRQ handler the channel(s). Sets the
|
|
; Reset bit for each channel; configures AMIC for the I/O bus speed of the machine.
|
|
;
|
|
; Note: Requires that ExpandMem and MemoryDispatch have been initalized.
|
|
;________________________________________________________________________________________
|
|
|
|
WITH MemDispGlobals, ExpandMemRec, DMADispGlobals
|
|
|
|
DMALogBufferAddrPDM EQU $61000000 ; Hard code this for now (This is the logical buffer address)
|
|
|
|
AMICInitPostProc
|
|
MOVEA.L UnivInfoPtr,A2
|
|
ADDA.L ProductInfo.DecoderInfoPtr(A2),A2 ; Get the addr of the universal base addresses
|
|
MOVEA.L DecoderInfo.AMICAddr(A2),A2 ; Get AMIC's DMA base address
|
|
|
|
MOVE.L ([LockMemCt],mdLog2PageSize),D1 ; Get the current log2 MMU page size
|
|
MOVE.L #DMALogBufferAddrPDM,D0 ; Get the hard coded logcal address of the DMA buffer
|
|
; that the nanokernel has allocated for us
|
|
LSR.L D1,D0 ; Turn the Log addr into a page number
|
|
|
|
MOVE.L D0,A0 ; Put the page in A0
|
|
_nkMMUGetPhysicalPage ; Get the physical page number in D0
|
|
LSL.L D1,D0 ; Turn the page into an address
|
|
|
|
; Issue a soft reset to all the DMA channels. Too bad a restart doesn't pull the RESET line.
|
|
|
|
MOVEQ #0,D1 ; Clear D1
|
|
LEA @AMICcontrolRegs,A0 ; Point to the table of offsets for the channel control regs
|
|
@ResetLoop MOVE.W (A0)+,D1 ; Get an offset
|
|
BEQ.S @ResetSound ; -> End of table reached.
|
|
BSET.B #0,(A2,D1) ; Set the channel Reset bit
|
|
BRA.S @ResetLoop ; -> Do it once for each channel
|
|
@ResetSound BCLR.B #0,$50F14010 ; Disable Sound Output <MC5>
|
|
BCLR.B #7,$50F14011 ; Disable Sound Input <MC5>
|
|
|
|
; Get the I/O bus speed and configure AMIC accordingly
|
|
|
|
@BusSpeed MOVE.L ([ProcessorInfoPtr],\
|
|
ProcessorInfo.BusClockRateHz),D1 ; Get the I/O bus clock rate
|
|
|
|
LEA @CommonClockRates,A0 ; Point to the list of clock rates
|
|
MOVEQ #3,D2 ; Start with the least delays (inverse)
|
|
@Lupe CMP.L (A0)+,D1 ; Is the bus clock rate less than the entry?
|
|
BLS.S @GotIt ; -> Yes, go with the current delay factor
|
|
DBRA D2,@Lupe ; -> Decrement the delay factor an loop again
|
|
@GotIt BFINS D2,AMICSCSIcntrl(A2){4,2} ; Put bits 0 & 1 from D2 into bits 2 & 3 in AMIC
|
|
|
|
; LSL.B #2,D2 ; Shift bits 0 & 1 over to 2 & 3.
|
|
; MOVEQ #$0C,D1 ; Make a mask for bits 2 & 3
|
|
; AND.B AMICSCSIcntrl(A2),D1 ; Mask out the bus speed bits
|
|
; OR.B D2,D1
|
|
; MOVE.B D1,AMICSCSIcntrl(A2) ; Get the SCSI DMA control byte
|
|
|
|
; Set the AMIC DMA buffer base address (the physical address in D0)
|
|
|
|
SWAP D0 ; Put the upper 16 significant bits into the lower 16
|
|
MOVE.B D0,AMICSCSIDMABase+1(A2) ; Write the Base Address 8 bits at a time
|
|
LSR.W #8,D0 ; Get the MSB
|
|
MOVE.B D0,AMICSCSIDMABase(A2) ; Write it (Amic ignores the lower 18 bits of the base)
|
|
|
|
; Create a dispatch table in the system heap for the system interrupt dispatcher.
|
|
|
|
MOVE.L #ddSize,D0 ; Size of the Dispatch table
|
|
_NewPtr ,Sys,Clear ; Get the RAM in the system heap (die if we don't get it)
|
|
|
|
move.l A0,([ExpandMem],emDMADispatchGlobals) ; Save our global ptr in ExpandMem
|
|
beq.b @Done ; ensure that we don't munch on vectors
|
|
|
|
MOVE.L A2,ddDMAbase(A0) ; Save AMIC's base address in the Table
|
|
|
|
; Initialize the table to point to the Uninitalized/Spurious IRQ vector.
|
|
; Slam the SCC handler address into the designated entries in the table.
|
|
|
|
MOVE.L BadIntVector, D1 ; Get the Addr of the spurious IRQ handler
|
|
MOVEQ #ddVectCount-1, D0 ; Get the number of vectors (zero-based)
|
|
@InitVector MOVE.L D1, ddVector0(A0,D0.L*8) ; Initialize each vector to Spurious
|
|
DBRA D0, @InitVector ; -> Loop till they're all done
|
|
|
|
LEA SccDecode, A2 ; Point to the SCC irq handler
|
|
MOVE.L A2, SCCLvl4Avector(A0) ; Stuff the address into the Table
|
|
MOVE.L A2, SCCLvl4Bvector(A0) ; Me too (for port B)
|
|
|
|
@Done RTS
|
|
|
|
@AMICcontrolRegs ; Table of offsets to each channel's control reg
|
|
DC.W AMICSCSICntrl
|
|
DC.W AMICEnetTxCntrl
|
|
DC.W AMICEnetRxCntrl
|
|
DC.W AMICFloppyCntrl
|
|
DC.W AMICSCCTxACntrl
|
|
DC.W AMICSCCRxACntrl
|
|
DC.W AMICSCCTxBCntrl
|
|
DC.W AMICSCCRxBCntrl
|
|
DC.W 0
|
|
|
|
@CommonClockRates ; PDM I/O bus clock rate mapping table
|
|
DC.L 25000000 ; 3: 33.001 MHz
|
|
DC.L 40000000 ; 2: 40.001 MHz
|
|
DC.L 40000000 ; 1: 50.001 MHz <SM44> pdw
|
|
DC.L 100000000 ; 0: 100.001 MHz
|
|
DC.L -1 ; end of table
|
|
|
|
ENDWITH ; {MemDispGlobals, ExpandMemRec, DMADispGlobals}
|
|
|
|
AMICDisableIntSources
|
|
movea.l VIA,a0 ; disable all interrupts in VIA1
|
|
move.b #$7F,vIER(a0)
|
|
movea.l VIA2RBV,a0
|
|
move.b #$7F,Rv2IER(a0) ; and in VIA2
|
|
|
|
move.l UnivInfoPtr,a0 ; get ptr to ProductInfo
|
|
add.l ProductInfo.DecoderInfoPtr(a0),a0 ; point to the base address table
|
|
move.l DecoderInfo.AMICAddr(a0),a0 ; get ptr to AMIC
|
|
move.b #(1<<DMARST),AMIC_DMA_RECV_CNTL(a0) ; reset DMA channel, disable ints
|
|
move.b #(1<<DMARST),AMIC_DMA_XMIT_CNTL(a0) ; reset DMA channel, disable ints
|
|
nop
|
|
|
|
TestFor MACEExists ; do we have MACE hardware? <GMR>
|
|
beq.s @exit ; no, skip
|
|
|
|
move.l UnivInfoPtr,a0 ; get ptr to ProductInfo
|
|
add.l ProductInfo.DecoderInfoPtr(a0),a0 ; point to the base address table
|
|
move.l DecoderInfo.MACEAddr(a0),a0 ; Save the MACE base address
|
|
; st.b MACE_INT_MSK(a0) ; Disable MACE ints. (I'll fix the equates later)
|
|
st.b $90(a0) ; Disable MACE ints.
|
|
nop
|
|
@exit rts
|
|
|
|
ENDIF ; {hasAMIC}
|
|
|
|
|
|
|
|
IF hasGrandCentral THEN
|
|
|
|
; - - - - - Grand Central primitives - - - - -
|
|
|
|
WITH ExpandMemRec, GCInterruptDispatchTable
|
|
|
|
GCInitPostProc
|
|
; build a table for the Grand Central interrupt dispatcher
|
|
move.l #GCInterruptDispatchTable.size,d0
|
|
_NewPtr ,sys,clear ; allocate memory for a dispatch table
|
|
move.l a0,([ExpandMem],emDMADispatchGlobals) ; save a reference to the table
|
|
beq @EndPostProc ; abort installation if no memory
|
|
|
|
; save the Grand Central base address in the interrupt dispatch table
|
|
movea.l UnivInfoPtr,a1
|
|
adda.l ProductInfo.DecoderInfoPtr(a1),a1
|
|
movea.l DecoderInfo.GrandCentralAddr(a1),a1
|
|
move.l a1,gcBaseAddr(a0)
|
|
|
|
; initialize dispatch vectors to the value of the spurious interrupt vector
|
|
move.l BadIntVector,d1
|
|
moveq #31,d0
|
|
@InitVector move.l d1,gcVector(a0,d0.l*8)
|
|
dbra d0,@InitVector
|
|
|
|
; enable the default VIA interrupt handler
|
|
_GCEnableInterruptSource gcifDevVia
|
|
|
|
; install the default SCC interrupt handlers
|
|
lea SccDecode,a0 ; default SCC interrupt handler
|
|
lea 0,a1 ; no reference constant
|
|
|
|
moveq #gcifDevSccA,d0
|
|
_GCRegisterHandler ; now serving port A
|
|
moveq #gcifDevSccB,d0
|
|
_GCRegisterHandler ; now serving port B
|
|
|
|
_GCEnableInterruptSource gcifDevSccA
|
|
_GCEnableInterruptSource gcifDevSccB
|
|
|
|
_GCEnableInterruptSource gcifExtNMI ; enable NMI <SM62>
|
|
|
|
@EndPostProc
|
|
rts
|
|
|
|
ENDWITH ; {ExpandMemRec, GCInterruptDispatchTable}
|
|
|
|
GCDisableIntSources
|
|
bsr.b GetGrandCentralBase
|
|
|
|
; clear all interrupt mask bits without changing the interrupt mode bit
|
|
andi.l #1 << gcifIntMode,gcInterruptMask(a0)
|
|
rts
|
|
|
|
GCEnableSoundInts
|
|
bsr.b GetGrandCentralBase
|
|
|
|
; set the audio interface interrupt enable bit
|
|
ori.l #1 << gcifDevAudio,gcInterruptMask(a0)
|
|
rts
|
|
|
|
GCDisableSoundInts
|
|
bsr.b GetGrandCentralBase
|
|
|
|
; clear the audio interface interrupt enable bit
|
|
andi.l #~(1 << gcifDevAudio),gcInterruptMask(a0)
|
|
rts
|
|
|
|
GCEnableSCSIInts
|
|
bsr.b GetGrandCentralBase
|
|
|
|
; set the SCSI interface interrupt enable bits
|
|
ori.l #1 << gcifDevSCSI0 | 1 << gcifDevSCSI1,gcInterruptMask(a0)
|
|
rts
|
|
|
|
GCDisableSCSIInts
|
|
bsr.b GetGrandCentralBase
|
|
|
|
; clear the SCSI interface interrupt enable bits
|
|
andi.l #~(1 << gcifDevSCSI0 | 1 << gcifDevSCSI1),gcInterruptMask(a0)
|
|
rts
|
|
|
|
GetGrandCentralBase
|
|
movea.l UnivInfoPtr,a0 ; get a pointer to ProductInfo
|
|
adda.l ProductInfo.DecoderInfoPtr(a0),a0 ; point to the base addresses table
|
|
movea.l DecoderInfo.GrandCentralAddr(a0),a0 ; get the Grand Central base address
|
|
rts
|
|
|
|
ENDIF ; {hasGrandCentral}
|
|
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Auto-Vector Interrupts
|
|
;
|
|
; The autovector routines save intRegs, (typically) perform their second
|
|
; level dispatch then jump to FinishInt to service Deferred Tasks and RTE.
|
|
; This jump to FinishInt may actually be an explicit BRA or it may be
|
|
; done by the autovector routine pushing (PEA) FinishInt then jumping to
|
|
; a second-level routine which will RTS into FinishInt. This is better than
|
|
; a JSR into the second-level routine followed by a BRA to FinishInt because
|
|
; the cache line containing the BRA may have been flushed during the second-
|
|
; level routine and when the RTS back to that BRA happens it will take a miss,
|
|
; causing a bus cycle. This is avoided by the PEA/JMP.
|
|
;
|
|
;
|
|
; The auto-vectors are assigned as below (according to interrupt priority level):
|
|
;
|
|
; Level 1: VIA1 interrupts, dispatched through Via1Int using Via1DT
|
|
;
|
|
; Level 2: VIA2/RBV interrupts, dispatched through Via2Int using Via2DT
|
|
;
|
|
; Level 3: Ethernet interrupts on some systems
|
|
;
|
|
; Level 4: SCC interrupts, dispatched through SccDecode using SccDT
|
|
; SCC IOP interrupts, dispatched through SccIopInt
|
|
;
|
|
; Level 5: DSP interrupts
|
|
;
|
|
; Level 6: unused
|
|
;
|
|
; Level 7: this interrupt is typically generated only by the debugger switch
|
|
;
|
|
;
|
|
; Routine: FinishInt - Service Deferred Tasks and RTE
|
|
;
|
|
; Inputs: The stack holds saved 'IntRegs' with an interrupt stack frame above.
|
|
; This routine is arrived at by a direct branch from the autovector routines.
|
|
;
|
|
; Outputs: none
|
|
; This routine exits by restoring the saved 'IntRegs' and performing RTE.
|
|
;
|
|
; Destroys: none
|
|
;
|
|
; Function: When the interrupt processing has been completed and this routine
|
|
; is branched to, it calls any queued deferred tasks (if returning
|
|
; to level zero), restores the saved registers, and returns
|
|
; from interrupt processing by an RTE instruction.
|
|
;
|
|
; USED TO:
|
|
; Provides a centralized handler for calling a secondary dispatcher.
|
|
;
|
|
; Creates a consistent environment for all secondary interrupt dispatchers,
|
|
; to allow them to easily decode the interrupt source and pass then on to
|
|
; other handlers. Registers A0-A3/D0-D3 are always preserved by the caller.
|
|
;
|
|
; The secondary interrupt dispatcher is called by a JSR and may either return
|
|
; with an RTS, or chain to another dispatcher.
|
|
;
|
|
; If the CPU has a PSC/DSP architecture, this routine calls the DSP Level 2
|
|
; handler, if one is present and if RTE will return to an interrupt mask < 2.
|
|
; For Sound compatibility with older systems, the DSP Level 5 handler installs
|
|
; a "deferred" Level 2 handler/parameter in the PSC Interrupt Table.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
align alignment ; align on cache line boundary
|
|
FinishInt
|
|
|
|
IF hasPSC THEN
|
|
|
|
; For systems supporting PSC/DSP only: run the special DSP Level 2 deferred tasks
|
|
; for backward compatibility with the VIA2-based sound architecture.
|
|
|
|
WITH ExpandMemRec, PSC_INT_TBL
|
|
|
|
TestFor PSCExists
|
|
beq.s @noPSCHere
|
|
|
|
moveq #$06,d0 ; mask for int level in saved SR ($0600)
|
|
and.b IntRegsSize(sp),d0 ; are we going to RTE to level 0 or 1?
|
|
bne.s @NoDTasks ; no, then certainly no deferred tasks to run
|
|
move sr,-(sp) ; save interrupt mask
|
|
ori #$0700,sr ; mask all ints
|
|
@chkagain move.l ExpandMem,a0
|
|
move.l emDMADispatchGlobals(a0),a0 ; get PSC interrupt table ptr
|
|
move.l DSPL2hndlr(a0),d0 ; DSP Level 2 hndlr need running?
|
|
beq.s @donelp ; no, leave
|
|
move.l DSPL2parm(a0),a1 ; pass DSP L2's parm
|
|
clr.l DSPL2hndlr(a0) ; remove DSP L2 hndlr from table
|
|
movea.l d0,a0
|
|
andi #$FAFF,sr ; set interrupt mask to 2
|
|
jsr (a0) ; call DSP L2 hndlr
|
|
ori #$0700,sr ; mask all ints
|
|
tst.w d0 ; check if DSP L2 hndlr succeeded
|
|
bne.s @chkagain ; yes, go check for another
|
|
@donelp move (sp)+,sr ; Restore interrupt mask
|
|
@noPSCHere
|
|
ENDWITH ; {ExpandMemRec, PSC_INT_TBL}
|
|
ENDIF
|
|
|
|
; Check for and dispatch deferred tasks.
|
|
; IMPORTANT!! - The following calculation depends on stack setup.
|
|
; Change stack usage only with extreme care!
|
|
|
|
ori.w #$0700,sr ; Block ints from tst of DTskQHdr to jDisptch/RTE
|
|
tst.l DTskQHdr ; Are there any deferred tasks in the queued up?
|
|
beq.s @NoDTasks ; -> No, just return.
|
|
|
|
moveq #$07,d0 ; mask for int level in saved SR ($0700)
|
|
and.b IntRegsSize(sp),d0 ; test upper byte of saved SR. Are we returning to Level 0?
|
|
bne.s @NoDTasks ; -> Yes, run defered tasks (the nominal case)
|
|
|
|
@DTDispatch movea.l jDisptch,a0 ; get jump vector for deferred task dispatcher
|
|
jsr (a0) ; dispatch the deferred tasks
|
|
|
|
@NoDTasks movem.l (sp)+,IntRegs ; restore registers
|
|
UnusedInt RTE ; and return from the interrupt
|
|
|
|
|
|
align alignment
|
|
JustRTS RTS ; unused dispatch table entry
|
|
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routines: Via1Int / Via2Int - Secondary Interrupt Dispatchers
|
|
; Inputs: none
|
|
; Outputs: A1 - base address of the interrupting VIA
|
|
; Destroys: A0, A1, D0
|
|
;
|
|
; Function: Decodes and prioritizes VIA interrupts, locates a handler
|
|
; for the highest priority enable VIA interrupt source in the Via1DT
|
|
; or Via2DT as shown below. The handler is jumped to, and it will return
|
|
; to the primary interrupt handler when done.
|
|
;
|
|
;
|
|
; Via1DT/Via2DT -> (00) CA2 highest priority
|
|
; (04) CA1 |
|
|
; (08) shift reg |
|
|
; (0C) CB2 |
|
|
; (10) CB1 |
|
|
; (14) T2 Timer \|/
|
|
; (18) T1 Timer V
|
|
; (1C) spurious: no interrupt pending lowest priority
|
|
;
|
|
; NOTE: The Via2Int routine is also used for RBV interrupts. This is possible
|
|
; because the VIA and RBV both have IER and IFR registers whose bits
|
|
; have the same meanings. The registers are at different offsets
|
|
; on the two chips, but if you .OR. the offsets, you can have common
|
|
; code to work with either chip. This is possible because the address
|
|
; bits used by the two chips don't overlap, and each chip happens to ignore
|
|
; the other chips address bits.
|
|
;_______________________________________________________________________
|
|
|
|
; "standard" VIA1 interrupt dispatcher
|
|
|
|
align alignment ; align on cache line boundary
|
|
Level1Via1Int
|
|
movem.l IntRegs,-(SP) ; preserve registers and push returnÉ
|
|
pea FinishInt ; Éaddr so on rts it goes to FinishInt
|
|
|
|
movea.l VIA,a1 ; get VIA1 base address
|
|
moveq.l #$7F,d0 ; mask for interrupt pending bits (clr high bit)
|
|
eieioSTP
|
|
and.b vIFR(a1),d0 ; get VIA interrupt pending flags
|
|
eieioSTP
|
|
and.b vIER(a1),d0 ; only process enabled interrupts
|
|
eieioSTP
|
|
movea.w PrioritizeViaInts(d0.w*2),a0 ; get the dispatch table offset
|
|
movea.l (a0),a0 ; get routine address from table
|
|
jmp (a0) ; dispatch to routine
|
|
|
|
|
|
; "standard" VIA2/RBV interrupt dispatcher
|
|
|
|
align alignment ; align on cache line boundary
|
|
Level2Via2Int
|
|
movem.l IntRegs,-(SP) ; preserve registers and push returnÉ
|
|
pea FinishInt ; Éaddr so on rts it goes to FinishInt
|
|
|
|
movea.l VIA2RBV,a1 ; get VIA2 or RBV base address
|
|
moveq.l #$7F,d0 ; mask for interrupt pending bits (clr high bit)
|
|
eieioSTP
|
|
and.b Rv2IFR(a1),d0 ; get VIA/RBV interrupt pending flags
|
|
eieioSTP
|
|
lea Via2DT-Via1DT,A0 ; bias to point to VIA2 interrupt dispatch table
|
|
eieioSTP
|
|
and.b Rv2IER(a1),d0 ; only process enabled interrupts
|
|
eieioSTP
|
|
adda.w PrioritizeViaInts(d0.w*2),a0 ; get the dispatch table offset
|
|
movea.l (a0),a0 ; get routine address from table
|
|
jmp (a0) ; dispatch to routine
|
|
|
|
|
|
IF hasPSC THEN
|
|
|
|
; VIA2 interrupt dispatcher for PSC
|
|
|
|
align alignment ; align on cache line boundary
|
|
PSCLevel2Via2Int
|
|
movem.l IntRegs,-(SP) ; preserve registers and push returnÉ
|
|
pea FinishInt ; Éaddr so on rts it goes to FinishInt
|
|
|
|
movea.l VIA2,a1 ; get VIA2 base address
|
|
moveq.l #$6F,d0 ; mask for interrupt pending bits (clr high bit)
|
|
And.b vIFR(a1),d0 ; get VIA/RBV interrupt pending flags
|
|
lea Via2DT-Via1DT,A0 ; bias to point to VIA2 interrupt dispatch table
|
|
And.b vIER(a1),d0 ; only process enabled interrupts
|
|
adda.w PrioritizeViaInts(d0.w*2),a0 ; get the dispatch table offset
|
|
movea.l (a0),a0 ; get routine address from table
|
|
jmp (a0) ; dispatch to routine
|
|
|
|
ENDIF ; {hasPSC}
|
|
|
|
|
|
; Priority encoding table, indexed by pending interrupt flag register, and returns
|
|
; the interrupt dispatch table address of the highest priority pending interrupt.
|
|
; Priority order is bit 0 is highest priority, bit 7 is lowest priority.
|
|
|
|
align alignment ; align on cache line boundary
|
|
PrioritizeViaInts
|
|
dc.w Via1DT+(4*7) ; 0 0 0 0 0 0 0 no bits set
|
|
dc.w Via1DT+(4*0) ; 0 0 0 0 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 0 0 0 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 0 0 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 0 0 0 0 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 0 0 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 0 0 0 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 0 0 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*3) ; 0 0 0 1 0 0 0 bit 3 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 0 1 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 0 0 1 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 0 1 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 0 0 0 1 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 0 1 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 0 0 1 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 0 1 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*4) ; 0 0 1 0 0 0 0 bit 4 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 1 0 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 0 1 0 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 1 0 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 0 0 1 0 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 1 0 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 0 1 0 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 1 0 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*3) ; 0 0 1 1 0 0 0 bit 3 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 1 1 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 0 1 1 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 1 1 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 0 0 1 1 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 1 1 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 0 1 1 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 0 1 1 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*5) ; 0 1 0 0 0 0 0 bit 5 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 0 0 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 1 0 0 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 0 0 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 0 1 0 0 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 0 0 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 1 0 0 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 0 0 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*3) ; 0 1 0 1 0 0 0 bit 3 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 0 1 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 1 0 1 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 0 1 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 0 1 0 1 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 0 1 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 1 0 1 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 0 1 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*4) ; 0 1 1 0 0 0 0 bit 4 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 1 0 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 1 1 0 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 1 0 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 0 1 1 0 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 1 0 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 1 1 0 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 1 0 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*3) ; 0 1 1 1 0 0 0 bit 3 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 1 1 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 1 1 1 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 1 1 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 0 1 1 1 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 1 1 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 0 1 1 1 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 0 1 1 1 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*6) ; 1 0 0 0 0 0 0 bit 6 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 0 0 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 0 0 0 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 0 0 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 1 0 0 0 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 0 0 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 0 0 0 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 0 0 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*3) ; 1 0 0 1 0 0 0 bit 3 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 0 1 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 0 0 1 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 0 1 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 1 0 0 1 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 0 1 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 0 0 1 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 0 1 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*4) ; 1 0 1 0 0 0 0 bit 4 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 1 0 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 0 1 0 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 1 0 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 1 0 1 0 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 1 0 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 0 1 0 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 1 0 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*3) ; 1 0 1 1 0 0 0 bit 3 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 1 1 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 0 1 1 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 1 1 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 1 0 1 1 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 1 1 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 0 1 1 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 0 1 1 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*5) ; 1 1 0 0 0 0 0 bit 5 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 0 0 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 1 0 0 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 0 0 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 1 1 0 0 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 0 0 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 1 0 0 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 0 0 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*3) ; 1 1 0 1 0 0 0 bit 3 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 0 1 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 1 0 1 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 0 1 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 1 1 0 1 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 0 1 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 1 0 1 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 0 1 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*4) ; 1 1 1 0 0 0 0 bit 4 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 1 0 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 1 1 0 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 1 0 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 1 1 1 0 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 1 0 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 1 1 0 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 1 0 1 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*3) ; 1 1 1 1 0 0 0 bit 3 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 1 1 0 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 1 1 1 0 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 1 1 0 1 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*2) ; 1 1 1 1 1 0 0 bit 2 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 1 1 1 0 1 bit 0 is highest priority
|
|
dc.w Via1DT+(4*1) ; 1 1 1 1 1 1 0 bit 1 is highest priority
|
|
dc.w Via1DT+(4*0) ; 1 1 1 1 1 1 1 bit 0 is highest priority
|
|
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: SonicInt Level 3 SONIC Ethernet Interrupt Dispatcher
|
|
;
|
|
; The SONIC Ethernet hardware is logically a slot device, so SonicInt
|
|
; simply chains to the appropriate slot handler at this time.
|
|
;_______________________________________________________________________
|
|
|
|
align alignment ; align on cache line boundary
|
|
IMPORT RunSlotHandlers
|
|
|
|
; RunSlotHandlers as if it were a slot #9 interrupt.
|
|
|
|
Level3SonicInt
|
|
movem.l IntRegs,-(SP) ; preserve registers and push returnÉ
|
|
pea FinishInt ; Éaddr so on rts it goes to FinishInt
|
|
|
|
moveq #9,d0
|
|
jmp RunSlotHandlers
|
|
|
|
|
|
|
|
IF hasIopScc THEN
|
|
;_______________________________________________________________________
|
|
; Routine: Level4SccIopInt ... Interrupt Dispatcher
|
|
;_______________________________________________________________________
|
|
|
|
align alignment ; align on cache line boundary
|
|
Level4SccIopInt
|
|
movem.l IntRegs,-(SP) ; preserve registers and push returnÉ
|
|
pea FinishInt ; Éaddr so on rts it goes to FinishInt
|
|
|
|
moveq.l #0,d0 ; SCC IOP is IOP number 0
|
|
eieioSTP
|
|
jmp IOPInterrupt ; handle the interrupt and return
|
|
eieioSTP
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: SccDecode 8530 SCC Interrupt Dispatcher
|
|
;
|
|
; All SCC interrupts: This interrupt dispatcher determines the actual
|
|
; interrupt source and dispatches through a table of secondary vectors
|
|
; maintained in low memory. The table looks like this:
|
|
;
|
|
; SccDT -> (00) channel B: transmit buffer empty
|
|
; (04) channel B: external/status
|
|
; (08) channel B: receive character available
|
|
; (0C) channel B: special receive condition
|
|
; (10) channel A: transmit buffer empty
|
|
; (14) channel A: external/status
|
|
; (18) channel A: receive character available
|
|
; (1C) channel A: special receive condition
|
|
;
|
|
; SccDT contains a long entry-point address for each of the eight primary
|
|
; interrupt routines corresponding to the eight primary interrupting sources.
|
|
;
|
|
; The two external status interrupts may be broken down into the following
|
|
; sources by the primary receiver:
|
|
;
|
|
; zero count (when the SCC baud rate generator is used as a timer)
|
|
; DCD transition
|
|
; sync/hunt (for synchronous serial modes only)
|
|
; CTS transition (external handshake in signal)
|
|
; Tx Underrun/EOM (for synchronous serial modes only)
|
|
; Break/abort (interrupts when break(async)/abort(sync) begins and ends)
|
|
;
|
|
; A secondary dispatch is made for external/status interrupts through
|
|
; the external/status dispatch table:
|
|
;
|
|
; ExtStsDT -> (00) ext/sts B - non-mouse
|
|
; (04) unused (formerly mouse vertical interrupt)
|
|
; (08) ext/sts A - non-mouse
|
|
; (0C) unused (formerly mouse horizontal interrupt)
|
|
;
|
|
; When dispatching the external/status handler, D0 contains the current
|
|
; status (read reg 0) and D1 the changed bits from the previous time
|
|
; an extenal/status interrupt was received. A reset ext/sts command is issued.
|
|
;
|
|
; The two special receive condition interrupts may also be further subdivided.
|
|
;
|
|
; end of frame (synchronous modes)
|
|
; CRC/framing error
|
|
; receiver overrun
|
|
; parity error
|
|
; all sent (asynchronous mode only)
|
|
;
|
|
; Each primary routine is entered with the processor priority masked, and with
|
|
; registers D0-D3 and A0-A3 available for use; A0 will point to SCC channel A/B
|
|
; control read address and A1 to SCC channel A/B control write address,
|
|
; depending upon which channel is interrupting:
|
|
;
|
|
; (READ ADDRESS) (WRITE ADDRESS)
|
|
;
|
|
; CHANNEL A/B DATA 4(A0) 4(A1)
|
|
;
|
|
; CHANNEL A/B CONTROL (A0) (A1)
|
|
;
|
|
; Each routine (except for external/status secondary routines) is responsible
|
|
; for clearing the source of the interrupt in the SCC, and for saving and
|
|
; restoring any additional registers used.
|
|
;
|
|
; SCC interrupt service routines should return by RTS to this dispatcher.
|
|
;
|
|
; The interrupt routine is selected by reading the SCC modified interrupt vector.
|
|
; The SCC selects the particular vector to supply according to a fixed priority:
|
|
;
|
|
; Receiver channel A (highest)
|
|
; Transmit channel A
|
|
; Ext/Status channel A
|
|
; Receiver channel B
|
|
; Transmit channel B
|
|
; Ext/Status channel B (lowest)
|
|
;
|
|
; The highest priority interrupt which is also enabled is selected by the SCC.
|
|
; Only processing one request at a time allows SccDecode to be re-entrant and
|
|
; service routines may lower the processor priority as soon as possible in
|
|
; order to process other pending interrupts.
|
|
;
|
|
;
|
|
; Optimization Note:
|
|
;
|
|
; Slower machines exhibit significant serial throughput problems particularly at
|
|
; relatively high baud rates. The most significant contribution to this problem
|
|
; is the simple overhead of running through the interrupt handler for every
|
|
; single character transmitted or received. The effects are most apparent when
|
|
; the 24-bit interrupt handler is frequently forced to swap MMU modes because
|
|
; SCC interrupts may arrive when the machine is in 32-bit mode.
|
|
;
|
|
; An interim approach to reducing the apparent problem is to NOT take an interrupt
|
|
; for each received character, but rather to empty out the SCC FIFO before returning
|
|
; to the primary interrupt dispatcher. This is not a complete solution! System-wide
|
|
; interrupt latency is still a problem and the small 3-byte FIFO in the SCC is not
|
|
; sufficient to overcome the latency now inherent in the traditional Mac OS.
|
|
;
|
|
; Relative to earlier versions of this dispatcher, the dispatcher is patched to call
|
|
; (i.e. JSR to) the serial driver's interrupt routines, rather than jumping to them.
|
|
; The service routine then returns to the secondary dispatcher, which checks to see if
|
|
; there is another character available. If there is another character pending, this
|
|
; dispatch routine loops to dispatch to the new interrupt (which must now be pending)
|
|
; rather than returning to the primary dispatcher (and repeatedly incurring the processor
|
|
; interrupt dispatch overhead).
|
|
;
|
|
; We do this ONLY FOR CHANNEL A, since it's the only one that's documented to be
|
|
; fast, and also so that LocalTalk won't pound us at its 230K baud rate.
|
|
;
|
|
; The Serial Driver Rx and SC interrupt service routines are patched in conjuction
|
|
; with this so that if a Device Manager request completes, we exit to the primary
|
|
; dispatcher regardless of whether a character is pending. This way we exit the
|
|
; interrupt handlers completely at least once per Device Manager request, allowing
|
|
; things like deferred tasks to run more in sequence.
|
|
;____________________________________________________________________________
|
|
|
|
align alignment ; align on cache line boundary
|
|
|
|
Level4SccInt
|
|
movem.l IntRegs,-(SP) ; preserve registers and push returnÉ
|
|
pea FinishInt ; Éaddr so on rts it goes to FinishInt
|
|
;fall into SccDecode
|
|
|
|
export SccDecode
|
|
SccDecode
|
|
MOVE.L SCCRd,A0 ; get SCC read address
|
|
MOVE.B (A0),D0 ; read to sync up SCC (just to be safe)
|
|
MOVE.L SCCWr,A1 ; get SCC channel B write control address
|
|
|
|
MOVE.B #2,(A1) ; point to SCC register 2, B channel
|
|
LEA SccDT,A2 ; point to dispatch table
|
|
MOVEQ #$0E,D0 ; AND mask
|
|
AND.B (A0),D0 ; read the modified interrupt vector
|
|
|
|
CMPI.B #8,D0 ; channel A interrupt?
|
|
bge.s GoChannelA ; branch if for A
|
|
MOVE.L (A2,D0.W*2),A2 ; get dispatch vector
|
|
jmp (A2) ; go run service routine
|
|
|
|
GoChannelA ADDQ #2,A0 ; adjust SCC addresses for port A
|
|
ADDQ #2,A1
|
|
MOVE.L (A2,D0.W*2),A2 ; get dispatch vector
|
|
jsr (A2) ; call service routine
|
|
|
|
; If the interrupt finished a Device Mgr request, then return directly to the
|
|
; primary interrupt dispatcher, otherwise we return and continue from here.
|
|
|
|
movea.l SCCRd,a0 ; point to SCC read base address
|
|
btst.b #RxCA,2(a0) ; SCC data available on channel A?
|
|
bne.s SccDecode ; data available, so dispatch again
|
|
|
|
SccIntDone rts ; done
|
|
|
|
|
|
|
|
;_______________________________________________________________
|
|
;
|
|
; Secondary Dispatch routines for SCC external status interrupts
|
|
;
|
|
; On Entry: A0.L = SCC read address (appropriate channel)
|
|
; A1.L = SCC write address (appropriate channel)
|
|
; D0-D3/A0-A3 have been saved.
|
|
;
|
|
; On Exit: A0.L, A1.L are still SCC ptrs
|
|
; D0.B = SCC RR0 status
|
|
; D1.B = SCC RR0 bits which changed since last interrupt
|
|
; SCCASts/SCCBSts = updated with new RR0 value
|
|
; A2/A3/D2/D3 are undefined.
|
|
;_______________________________________________________________
|
|
|
|
align alignment ; align on cache line boundary
|
|
ExtBInt MOVE.B (A0),D0 ; * read SCC RR0 status for channel B
|
|
LEA SCCBSts,A3 ; old register value
|
|
LEA ExtStsDT,A2 ; point to channel B dispatch vectors
|
|
BRA.S ExtABInt ; share some code
|
|
|
|
align alignment ; align on cache line boundary
|
|
ExtAInt MOVE.B (A0),D0 ; * read SCC RR0 status for channel A
|
|
LEA SCCASts,A3 ; old register value
|
|
LEA ExtStsDT+8,A2 ; point to channel A dispatch vectors
|
|
|
|
ExtABInt MOVE.B #15,(A1) ; * point to SCC register 15,
|
|
; appropriate channel
|
|
MOVE.B (A3),D1 ; get old status
|
|
MOVE.B D0,(A3) ; update the old
|
|
EOR.B D0,D1 ; get changed bits
|
|
AND.B (A0),D1 ; * only look at enabled ext/sts bits
|
|
MOVE.B #$10,(A1) ; * clear the ext/status interrupt
|
|
|
|
MOVE.L (A2),A2 ; get the vector
|
|
JMP (A2) ; go to it
|
|
|
|
|
|
|
|
IF hasPSC THEN
|
|
|
|
WITH ExpandMemRec, PSC_INT_TBL
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Level3PSCInt
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Destroys: D0, D1, A0, A1
|
|
;
|
|
; Called by: autovectored int
|
|
;
|
|
; Calls: Level 3 Interrupt handlers, if installed in PSC_INT_TBL
|
|
;
|
|
; Notes: Does NOT loop like other dispatchers since only servicing
|
|
; one int. source.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
align alignment ; align on cache line boundary
|
|
Level3PSCInt
|
|
movem.l IntRegs,-(sp) ; preserve registers
|
|
|
|
Move.L UnivInfoPtr, A0 ; get ptr to ProductInfo
|
|
Add.L ProductInfo.DecoderInfoPtr(A0), A0 ; point to the base address table
|
|
Move.L DecoderInfo.PSCAddr(A0), A0 ; get the PSC base address in A0
|
|
|
|
Move.l ExpandMem, A1
|
|
Move.l emDMADispatchGlobals(A1), A1 ; Get PSC Int. Table base
|
|
|
|
; PSC feature: read Int. reg until 2 reads produce same result
|
|
@chkagain Move.b L3IR(A0), D1 ; get L3 int status
|
|
Cmp.b L3IR(A0), D1 ; do they match?
|
|
Bne.s @chkagain ; no, read until matches
|
|
|
|
AndI.b #(1<<MACE), D1
|
|
And.b L3IER(A0), D1 ; an enabled int. to service?
|
|
beq FinishInt ; no -> check for Deferred Tasks and RTE
|
|
|
|
@gohandler Move.l MACEhndlr(A1), D0 ; get handler
|
|
beq FinishInt ; no -> check for Deferred Tasks and RTE
|
|
Move.l D0, A0
|
|
Move.l MACEparm(A1), A1 ; get handler's parm
|
|
pea FinishInt ; push addr so on rts it goes to FinishInt
|
|
jmp (A0) ; call handler
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Level4PSCInt
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Destroys: D0, A0, A1
|
|
;
|
|
; Called by: autovectored int
|
|
;
|
|
; Calls: Level 4 Interrupt handlers, if installed in PSC_INT_TBL
|
|
;
|
|
; Notes: All DMA interrupts are handled as if the DMA controller were
|
|
; a single device interrupting at level 4. Hence, PSCDMADispatch
|
|
; is subordinate to this dispatcher.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
align alignment ; align on cache line boundary
|
|
Level4PSCInt
|
|
movem.l IntRegs,-(sp) ; preserve registers
|
|
|
|
MoveM.l A4/A5/D5, -(SP) ; save not-interrupt regs
|
|
Move.L UnivInfoPtr, A0 ; get ptr to ProductInfo
|
|
Add.L ProductInfo.DecoderInfoPtr(A0), A0 ; point to the base address table
|
|
Move.L DecoderInfo.PSCAddr(A0), A5 ; get the PSC base address in A5
|
|
|
|
Move.l ExpandMem, A4
|
|
Move.l emDMADispatchGlobals(A4), A4 ; Get PSC Int. Table base
|
|
|
|
; PSC feature: read int reg until 2 reads produce same result
|
|
@chkagain Move.b L4IR(A5), D5 ; get L4 int status
|
|
Cmp.b L4IR(A5), D5 ; do they match?
|
|
Bne.s @chkagain ; no, read until matches
|
|
|
|
; another enabled int. to service?
|
|
AndI.b #(1<<L4SCCA)+(1<<L4SCCB)+(1<<SNDSTAT)+(1<<DMA), D5
|
|
And.b L4IER(A5), D5
|
|
Beq.s @exit ; no, leave
|
|
|
|
@chkscca BTst #L4SCCA, D5 ; SCCA int?
|
|
Beq.s @chksccb ; no
|
|
Move.l L4SCCAhndlr(A4), D0 ; get handler
|
|
Beq.s @chksccb ; no handler, chk other L4 int sources
|
|
Move.l D0, A0
|
|
Move.l L4SCCAparm(A4), A1 ; get handler's parm
|
|
Jsr (A0) ; call handler
|
|
|
|
@chksccb BTst #L4SCCB, D5 ; SCCB int?
|
|
Beq.s @chksnd ; no
|
|
Move.l L4SCCBhndlr(A4), D0 ; get handler
|
|
Beq.s @chksnd ; no handler, chk other L4 int sources
|
|
Move.l D0, A0
|
|
Move.l L4SCCBparm(A4), A1 ; get handler's parm
|
|
Jsr (A0) ; call handler
|
|
|
|
@chksnd BTst #SNDSTAT, D5 ; Singer CODEC sound int?
|
|
Beq.s @chkdma ; no
|
|
Move.l SNDSTAThndlr(A4), D0 ; get handler
|
|
Beq.s @chkdma ; no handler, chk other L4 int sources
|
|
Move.l D0, A0
|
|
Move.l SNDSTATparm(A4), A1 ; get handler's parm
|
|
Jsr (A0) ; call handler
|
|
|
|
@chkdma BTst #DMA, D5 ; DMA int?
|
|
Beq.s @chkagain ; no
|
|
Bsr.s PSCDMADispatch ; call dma int dispatcher
|
|
; A4,A5 must be initialized
|
|
Bra.s @chkagain ; go see if another L4 int. occurred
|
|
|
|
@exit MoveM.l (SP)+, A4/A5/D5 ; restore non-interrupt regs
|
|
bra FinishInt ; check for Deferred Tasks and RTE
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: PSCDMADispatch
|
|
; Loops calling a DMA Interrupt Handler, if installed, for each
|
|
; interrupting DMA channel as indicated by the PSC's Interrupt
|
|
; Status Register.
|
|
;
|
|
; Inputs: A5 - PSC base address
|
|
; A4 - PSC Interrupt table base address
|
|
;
|
|
; Destroys: D0,A0,A1
|
|
;
|
|
; Called by: Level4PSCInt
|
|
;
|
|
; Calls: DMA channel interrupt handler obtained from PSC Interrupt Table
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
align alignment ; align on cache line boundary
|
|
PSCDMADispatch
|
|
MoveM.l A6/D4/D5, -(SP) ; save non-interrupt regs
|
|
|
|
Lea DMA_hndlrs(A4),A6 ; get address of start of DMA int hndlrs
|
|
|
|
; PSC feature: read Int. reg until 2 reads produce same result
|
|
@chkagain Move.l PSC_ISR(A5), D5 ; get L4 int enable
|
|
Cmp.l PSC_ISR(A5), D5 ; do they match?
|
|
Bne.s @chkagain ; no, read until matches
|
|
|
|
@chkisr BFFFO D5{0:8}, D4 ; get highest pri interrupting channel
|
|
Beq.s @noints ; no (more) int sources, leave
|
|
|
|
Move.l (A6, D4*8), D0 ; get chnl int handler
|
|
Beq.s @nextchan
|
|
Move.l D0, A0
|
|
Move.l 4(A6, D4*8), A1 ; get hndlr's parm
|
|
Jsr (A0) ; call chnl int handler
|
|
|
|
@nextchan BFClr D5{D4:1} ; clear bit in D5 for int just processed
|
|
Bra.s @chkisr ; go chk other chnl ints
|
|
|
|
@noints MoveM.l (SP)+, A6/D4/D5 ; restore non-interrupt regs
|
|
RTS
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Level5PSCInt
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Destroys: D0, A0, A1
|
|
;
|
|
; Called by: autovectored int
|
|
;
|
|
; Calls: Level 5 Interrupt handlers, if installed in PSC_INT_TBL
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
align alignment ; align on cache line boundary
|
|
Level5PSCInt
|
|
movem.l IntRegs,-(sp) ; preserve registers
|
|
|
|
MoveM.l A4/A5/D5, -(SP) ; save not-interrupt regs
|
|
Move.L UnivInfoPtr, A0 ; get ptr to ProductInfo
|
|
Add.L ProductInfo.DecoderInfoPtr(A0), A0 ; point to the base address table
|
|
Move.L DecoderInfo.PSCAddr(A0), A5 ; get the PSC base address in A5
|
|
|
|
Move.l ExpandMem, A4
|
|
Move.l emDMADispatchGlobals(A4), A4 ; Get PSC Int. Table base
|
|
|
|
; PSC feature: read int reg until 2 reads produce same result
|
|
@chkagain Move.b L5IR(A5), D5 ; get L5 int status
|
|
Cmp.b L5IR(A5), D5 ; do they match?
|
|
Bne.s @chkagain ; no, read until matches
|
|
|
|
; another enabled int. to service?
|
|
AndI.b #(1<<DSP)+(1<<FRMOVRN), D5
|
|
And.b L5IER(A5), D5
|
|
Beq.s @exit ; no, leave
|
|
|
|
@chkdsp BTst #DSP, D5 ; DSP int?
|
|
Beq.s @chkfrmovrn ; no
|
|
Move.l DSPhndlr(A4), D0 ; get handler
|
|
Beq.s @chkfrmovrn ; no handler, chk other L5 int sources
|
|
Move.l D0, A0
|
|
Move.l DSPparm(A4), A1 ; get handler's parm
|
|
Jsr (A0) ; call handler
|
|
|
|
@chkfrmovrn BTst #FRMOVRN, D5 ; FRMOVRN int?
|
|
Beq.s @chkagain ; no
|
|
Move.l FRMOVRNhndlr(A4), D0 ; get handler
|
|
Beq.s @chkagain ; no handler, loop
|
|
Move.l D0, A0
|
|
Move.l FRMOVRNparm(A4), A1 ; get handler's parm
|
|
Jsr (A0) ; call handler
|
|
|
|
Bra.s @chkagain ; go see if another L5 int. occurred
|
|
|
|
@exit MoveM.l (SP)+, A4/A5/D5 ; restore non-interrupt regs
|
|
bra FinishInt ; check for Deferred Tasks and RTE
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Level6PSCInt
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Destroys: D0, A0, A1
|
|
;
|
|
; Called by: autovectored int
|
|
;
|
|
; Calls: Level 6 Interrupt handlers, if installed in PSC_INT_TBL
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
align alignment ; align on cache line boundary
|
|
Level6PSCInt
|
|
movem.l IntRegs,-(sp) ; preserve registers
|
|
|
|
MoveM.l A4/A5/D5, -(SP) ; save not-interrupt regs
|
|
Move.L UnivInfoPtr, A0 ; get ptr to ProductInfo
|
|
Add.L ProductInfo.DecoderInfoPtr(A0), A0 ; point to the base address table
|
|
Move.L DecoderInfo.PSCAddr(A0), A5 ; get the PSC base address in A5
|
|
|
|
Move.l ExpandMem, A4
|
|
Move.l emDMADispatchGlobals(A4), A4 ; Get PSC Int. Table base
|
|
|
|
; PSC feature: read int reg until 2 reads produce same result
|
|
@chkagain Move.b L6IR(A5), D5 ; get L6 int status
|
|
Cmp.b L6IR(A5), D5 ; do they match?
|
|
Bne.s @chkagain ; no, read until matches
|
|
|
|
; another enabled int. to service?
|
|
AndI.b #(1<<L660HZ)+(1<<L6SCCA)+(1<<L6SCCB), D5
|
|
And.b L6IER(A5), D5
|
|
Beq.s @exit ; no, leave
|
|
|
|
@chk60hz BTst #L660HZ, D5 ; 60.15 HZ int?
|
|
Beq.s @chkscca ; no
|
|
Move.l L660HZhndlr(A4), D0 ; get handler
|
|
Beq.s @chkscca ; no handler, chk other L6 int sources
|
|
Move.l D0, A0
|
|
Move.l L660HZparm(A4), A1 ; get handler's parm
|
|
Jsr (A0) ; call handler
|
|
|
|
@chkscca BTst #L6SCCA, D5 ; SCC Port A int?
|
|
Beq.s @chksccb ; no
|
|
Move.l L6SCCAhndlr(A4), D0 ; get handler
|
|
Beq.s @chksccb ; no handler, chk other L6 int sources
|
|
Move.l D0, A0
|
|
Move.l L6SCCAparm(A4), A1 ; get handler's parm
|
|
Jsr (A0) ; call handler
|
|
|
|
@chksccb BTst #L6SCCB, D5 ; SCC Port B int?
|
|
Beq.s @chkagain ; no
|
|
Move.l L6SCCBhndlr(A4), D0 ; get handler
|
|
Beq.s @chkagain ; no handler, loop
|
|
Move.l D0, A0
|
|
Move.l L6SCCBparm(A4), A1 ; get handler's parm
|
|
Jsr (A0) ; call handler
|
|
|
|
Bra.s @chkagain ; go see if another L6 int. occurred
|
|
|
|
@exit MoveM.l (SP)+, A4/A5/D5 ; restore non-interrupt regs
|
|
bra FinishInt ; check for Deferred Tasks and RTE
|
|
|
|
ENDWITH ; {ExpandMemRec, PSC_INT_TBL}
|
|
|
|
ENDIF ; {hasPSC}
|
|
|
|
|
|
|
|
IF hasAMIC THEN
|
|
|
|
WITH ExpandMemRec, DMADispGlobals
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Level3AMICInt / PDMMACEHndlr
|
|
;
|
|
; Called by: autovectored int
|
|
;
|
|
; Calls: MACE level 3 interrupt handler
|
|
;
|
|
; Notes: MACE should be the only device interrupting at this level, so
|
|
; dispatch to the MACE interrupt handler is unconditional. Also,
|
|
; the dispatcher does not loop since consecutive MACE interrupts
|
|
; are unlikely.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
align alignment ; align on cache line boundary
|
|
Level3AMICInt
|
|
movem.l IntRegs,-(SP) ; preserve registers and push returnÉ
|
|
pea FinishInt ; Éaddr so on rts it goes to FinishInt
|
|
|
|
movea.l ([ExpandMem],emDMADispatchGlobals), A1 ; get dispatch table base address
|
|
|
|
movea.l maceVector(A1), A0 ; get handler vector from table
|
|
movea.l maceRefcon(A1), A1 ; get handler refcon from table
|
|
jmp (a0) ; chain through handler
|
|
|
|
|
|
;_____________________________________________________________________________
|
|
; Routine: Level4AMICInt / PDMDMAHndlr
|
|
;
|
|
; Called by: autovectored int
|
|
;
|
|
; PDM DMA Interrupt Dispatcher
|
|
;
|
|
; Currently PDM's DMA irq comes in at Level 4. This routine is responsible
|
|
; for dispatching to one routine per irq according to the AMIC DMA Irq flag
|
|
; registers. Priority has been arbitrarily set according to bit field offsets
|
|
; in the flag registers.
|
|
;
|
|
; PDM's SCC irq is also at level 4, so to reduce SCC irq latency, this routine
|
|
; checks for SCC irqs first before looking for DMA interrupts.
|
|
;
|
|
; The positions in the table define the priority (lower entries are found first).
|
|
; The entries in the table are defined as follows (from left to right; highest
|
|
; priority to lowest):
|
|
;
|
|
; SCC | SndOut | SndIn | Unused | Floppy | EnetTx | EnetRx | TxA | RxA | TxB | RxB
|
|
;
|
|
; Remember the SCC is checked first. It has the highest priority, followed by
|
|
; DMA interrupts in the order listed above.
|
|
;_____________________________________________________________________________
|
|
|
|
align alignment ; align on cache line boundary
|
|
Level4AMICInt
|
|
movem.l IntRegs,-(sp) ; preserve registers
|
|
|
|
; Check for an SCC interrupt.
|
|
|
|
@loop btst #2,AMICIrqBase+AMICIrqFlags ; is any SCC interrupt pending (port A or B)?
|
|
bne.s @isSCC
|
|
|
|
; If we're here, then no SCC irq. Dispatch to appropriate DMA handler.
|
|
|
|
@notSCC move.b AMICIrqBase+AmicDMAFlags1,d0 ; Get the second byte of IRQ flags
|
|
lsl.w #8,d0
|
|
move.b AMICIrqBase+AmicDMAFlags0,d0 ; Get the first byte of IRQ flags
|
|
bfffo d0{22:10},d0 ; Get highest pri interrupting channel
|
|
beq FinishInt ; No bits set, -> check for Defrd Tasks and RTE
|
|
eori.w #31,d0 ; Make lsb 0 based
|
|
|
|
@GotOne move.l ([ExpandMem],emDMADispatchGlobals),a0 ; Get the ptr to our globals from expandmem
|
|
move.l ddRefCon0(a0,d0*8),a1 ; Load this handler's refCon
|
|
move.l ddVector0(a0,d0*8),a0 ;
|
|
move.w sr,-(sp)
|
|
jsr (A0) ; Call the guy
|
|
move.w (sp)+,sr
|
|
bra.b @loop ; see if more level 4's pending...
|
|
|
|
|
|
; Got an SCC interrupt.
|
|
|
|
@isSCC
|
|
move.w sr,-(sp)
|
|
movea.l ([ExpandMem],emDMADispatchGlobals), A1 ; get dispatch table base address
|
|
move.b #2,([SCCWr],bCtl) ; point to SCC register 2, B channel
|
|
nop
|
|
btst #3,([SCCRd],bCtl) ; test the interrupting channel status bit
|
|
bne.s @portA ; bit set for port A
|
|
@portB
|
|
movea.l SCCLvl4Bvector(A1), A0 ; get handler vector from table
|
|
movea.l SCCLvl4Brefcon(A1), A1 ; get handler refcon from table
|
|
jsr (A0) ; Call the guy
|
|
move.w (sp)+,sr
|
|
bra.b @loop ; see if more level 4's pending...
|
|
@portA
|
|
movea.l SCCLvl4Avector(A1), A0 ; get handler vector from table
|
|
movea.l SCCLvl4Arefcon(A1), A1 ; get handler refcon from table
|
|
jsr (A0) ; Call the guy
|
|
move.w (sp)+,sr
|
|
bra.b @loop ; see if more level 4's pending...
|
|
|
|
ENDWITH ; {ExpandMemRec, DMADispGlobals}
|
|
|
|
ENDIF ; {hasAMIC}
|
|
|
|
|
|
|
|
IF hasGrandCentral THEN
|
|
|
|
WITH ExpandMemRec, GCInterruptDispatchTable
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Level2GCInt
|
|
;
|
|
; Called by: autovectored interrupt
|
|
;
|
|
; Calls: level 2 interrupt handlers
|
|
;
|
|
; Notes: Grand Central does not implement a VIA2, although it reports
|
|
; any number of level 2 interrupts.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
gcL2Ints equ 1 << gcifDevSCSI0 |\
|
|
1 << gcifDevSCSI1 |\
|
|
1 << gcifDevAudio |\
|
|
1 << gcifDevSwim3 |\
|
|
1 << gcifExtPci0 |\
|
|
1 << gcifExtPci1 |\
|
|
1 << gcifExtSlot0 |\
|
|
1 << gcifExtSlot1 |\
|
|
1 << gcifExtSlot2 |\
|
|
1 << gcifExtSwatch0 |\
|
|
1 << gcifExtSwatch1 |\
|
|
1 << gcifExtJivi |\
|
|
1 << gcifExtGotham |\
|
|
1 << gcifExtSpare
|
|
|
|
align alignment ; align on cache line boundary
|
|
Level2GCInt
|
|
movem.l IntRegs,-(sp)
|
|
|
|
@CheckLevels
|
|
movea.l ([ExpandMem],emDMADispatchGlobals),a1 ; get dispatch table base address
|
|
movea.l gcBaseAddr(a1),a0 ; get Grand Central base address
|
|
|
|
move.l #gcL2Ints,d0 ; mask to examine SCC device interrupts
|
|
and.l gcInterruptLevels(a0),d0 ; did either SCC channel interrupt?
|
|
beq FinishInt
|
|
|
|
@DispatchL2
|
|
bfffo d0{0:32},d0 ; get an index for the first source
|
|
eori #31,d0 ; convert bit field offset to bit number
|
|
|
|
movea.l gcVector(a1,d0.l*8),a0 ; get handler vector from dispatch table
|
|
movea.l gcRefCon(a1,d0.l*8),a1 ; get handler refcon from dispatch table
|
|
jsr (a0) ; call handler
|
|
|
|
bra.b @CheckLevels ; loop until no level 2 interrupts pending
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Level3GCInt
|
|
;
|
|
; Called by: autovectored interrupt
|
|
;
|
|
; Calls: MACE level 3 interrupt handler
|
|
;
|
|
; Notes: MACE should be the only device interrupting at this level, so
|
|
; dispatch to the MACE interrupt handler is unconditional. Also,
|
|
; the dispatcher does not loop since consecutive MACE interrupts
|
|
; are unlikely.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
align alignment ; align on cache line boundary
|
|
Level3GCInt
|
|
movem.l IntRegs,-(sp)
|
|
pea FinishInt
|
|
|
|
movea.l ([ExpandMem],emDMADispatchGlobals),a1 ; get dispatch table base address
|
|
|
|
moveq #gcifDevMACE,d0 ; hard-code index for MACE vector
|
|
|
|
movea.l gcVector(a1,d0.l*8),a0 ; get handler vector from dispatch table
|
|
movea.l gcRefCon(a1,d0.l*8),a1 ; get handler refcon from dispatch table
|
|
jmp (a0) ; chain through handler
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: Level4GCInt
|
|
;
|
|
; Called by: autovectored interrupt
|
|
;
|
|
; Calls: SCC and DMA level 4 interrupt handlers
|
|
;
|
|
; Notes: The SCC device interrupts are examined first in order that they
|
|
; may be serviced with higher priority than the other interrupts
|
|
; at this level, which are a variety of DMA interrupts.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
gcL4SCCInts equ 1 << gcifDevSccA |\
|
|
1 << gcifDevSccB
|
|
|
|
gcL4DMAInts equ 1 << gcifDmaSCSI0 |\
|
|
1 << gcifDmaFloppy |\
|
|
1 << gcifDmaEthTx |\
|
|
1 << gcifDmaEthRx |\
|
|
1 << gcifDmaSccATx |\
|
|
1 << gcifDmaSccARx |\
|
|
1 << gcifDmaSccBTx |\
|
|
1 << gcifDmaSccBRx |\
|
|
1 << gcifDmaAudOut |\
|
|
1 << gcifDmaAudIn |\
|
|
1 << gcifDmaSCSI1
|
|
|
|
align alignment ; align on cache line boundary
|
|
Level4GCInt
|
|
movem.l IntRegs,-(sp)
|
|
|
|
@CheckLevels
|
|
movea.l ([ExpandMem],emDMADispatchGlobals),a1 ; get dispatch table base address
|
|
movea.l gcBaseAddr(a1),a0 ; get Grand Central base address
|
|
|
|
move.l gcInterruptLevels(a0),d1 ; take a snapshot of the interrupt levels
|
|
|
|
move.l #gcL4SCCInts,d0 ; mask to examine SCC device interrupts
|
|
and.l d1,d0 ; did either SCC channel interrupt?
|
|
bne.b @DispatchL4
|
|
|
|
move.l #gcL4DMAInts,d0 ; mask to examine DMA channel interrupts
|
|
and.l d1,d0 ; did any DMA channel interrupt?
|
|
beq FinishInt
|
|
|
|
@DispatchL4
|
|
bfffo d0{0:32},d0 ; get an index for the first source
|
|
eori #31,d0 ; convert bit field offset to bit number
|
|
|
|
movea.l gcVector(a1,d0.l*8),a0 ; get handler vector from dispatch table
|
|
movea.l gcRefCon(a1,d0.l*8),a1 ; get handler refcon from dispatch table
|
|
jsr (a0) ; call handler
|
|
|
|
bra.b @CheckLevels ; loop until no level 4 interrupts pending
|
|
|
|
|
|
ENDWITH ; {GCInterruptDispatchTable}
|
|
|
|
ENDIF ; {hasGrandCentral}
|
|
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Routine: InitIntHandler
|
|
;
|
|
; Inputs: none
|
|
;
|
|
; Outputs: none
|
|
;
|
|
; Trashes: D0/A0-A2
|
|
;
|
|
; Function: Initializes all interrupt vectors and the dispatch tables associated with them.
|
|
;
|
|
; For 68K systems, this is:
|
|
; AutoInt1-AutoInt6 68K interrupt vectors
|
|
; Lvl1DT level 1 (VIA1) interrupt dispatch table
|
|
; Lvl2DT level 2 interrupt dispatch table (level 4 SCC interrupts)
|
|
; ExtStsDT SCC ext/sts secondary dispatch table
|
|
; VIA2DT level 2 (VIA2/RBV/...) interrupt dispatch table
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
align alignment ; align on cache line boundary
|
|
export InitIntHandler
|
|
InitIntHandler
|
|
MOVEA.L UnivInfoPtr,A2 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A2),A2 ; then to the interrupt handlers primitives table,
|
|
LEA intFirstVectTbl(A2),A2 ; and finally to the first vectors table
|
|
BRA.S @FirstTable
|
|
|
|
@NextTable MOVEA.L A2,A0 ; point to the start of the table
|
|
ADD.L D0,A0
|
|
MOVE.L (A0)+,A1 ; get the starting RAM vector address
|
|
BRA.S @StartCopy
|
|
|
|
@CopyToRAM ADD.L A0,D0 ; convert the offset to absolute
|
|
MOVE.L D0,(A1)+ ; and copy it to a RAM vector
|
|
@StartCopy MOVE.L (A0)+,D0 ; get the next offset; end of table?
|
|
BNE.S @CopyToRAM ; -> no, go copy it out
|
|
|
|
@FirstTable MOVE.L (A2)+,D0 ; get the next table; end of list?
|
|
BNE.S @NextTable ; -> no, copy that table
|
|
|
|
MOVEA.L UnivInfoPtr,A2 ; point to the machine's product info,
|
|
ADDA.L IntHandlerPtr(A2),A2 ; then to the interrupt handlers primitives table,
|
|
ADDA.L intInitPostProc(A2),A2 ; and finally to the post proc routine
|
|
JMP (A2) ; call it
|
|
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Interrupt Initialization Tables
|
|
;
|
|
; These are the machine and/or feature specific interrupt tables tied
|
|
; to each machine's ProductInfo table in UniversalTables.a. They point
|
|
; to routines to turn interrupt sources on and off, and to set up the
|
|
; main interrupt vectors, plus any dispatch tables associated with a
|
|
; particular interrupt level.
|
|
;_______________________________________________________________________
|
|
|
|
; "standard" level 1-6 interrupt handlers vector table
|
|
|
|
StdAutoInts DC.L AutoInt1 ; starting vector address
|
|
DC.L Level1Via1Int-(*+4) ; level 1 interrupt handler
|
|
DC.L Level2Via2Int-(*+4) ; level 2 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 3 interrupt handler
|
|
DC.L Level4SccInt-(*+4) ; level 4 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 5 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 6 interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
; level 1-6 interrupt handlers vector table for machines with a SONIC chip
|
|
|
|
SONICAutoInts
|
|
DC.L AutoInt1 ; starting vector address
|
|
DC.L Level1Via1Int-(*+4) ; level 1 interrupt handler
|
|
DC.L Level2Via2Int-(*+4) ; level 2 interrupt handler
|
|
DC.L Level3SonicInt-(*+4) ; level 3 interrupt handler
|
|
DC.L Level4SccInt-(*+4) ; level 4 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 5 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 6 interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
|
|
; "standard" Lvl1DT and Lvl2DT vectors table
|
|
|
|
StdLvl12DT DC.L Lvl1DT ; starting vector address
|
|
|
|
; Lvl1DT starts here
|
|
DC.L OneSecInt-(*+4) ; VIA1 CA2 interrupt handler --- jOneSecInt
|
|
DC.L VBLInt-(*+4) ; VIA1 CA1 interrupt handler --- jVBLInt
|
|
DC.L JustRTS-(*+4) ; VIA1 SR interrupt handler --- jKbdADBInt
|
|
DC.L JustRTS-(*+4) ; VIA1 CB2 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA1 CB1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA1 T2 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA1 T1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA1 "any" interrupt handler
|
|
|
|
; Lvl2DT starts here
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L ExtBInt-(*+4) ; SCC channel B external/status interrupt
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L JustRTS-(*+4) ;
|
|
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L ExtAInt-(*+4) ; SCC channel A external/status interrupt
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L 0 ; end of table
|
|
|
|
|
|
; "standard" secondary dispatch vectors for SCC interrupts
|
|
|
|
StdExtStsDT DC.L ExtStsDT ; starting vector address
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L JustRTS-(*+4) ;
|
|
DC.L 0 ; end of table
|
|
|
|
|
|
; dispatch vectors for VIA2 interrupts with various incarnations of VIA2
|
|
|
|
IMPORT VIA2SlotInt
|
|
StdVIA2DT DC.L Via2DT ; starting vector address
|
|
DC.L JustRTS-(*+4) ; VIA2 CA2 interrupt handler
|
|
DC.L VIA2SlotInt-(*+4) ; VIA2 CA1 interrupt handler --- jSlotInt
|
|
DC.L JustRTS-(*+4) ; VIA2 SR interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 CB2 interrupt handler --- jSCSIIrqInt
|
|
DC.L JustRTS-(*+4) ; VIA2 CB1 interrupt handler --- jASCInt
|
|
DC.L JustRTS-(*+4) ; VIA2 T2 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 T1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 "any" interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
|
|
IF hasRBV THEN
|
|
|
|
IMPORT RbvSlotInt
|
|
RBVVIA2DT DC.L Via2DT ; starting vector address
|
|
DC.L JustRTS-(*+4) ; VIA2 CA2 interrupt handler
|
|
DC.L RbvSlotInt-(*+4) ; VIA2 CA1 interrupt handler --- jSlotInt
|
|
DC.L JustRTS-(*+4) ; VIA2 SR interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 CB2 interrupt handler --- jSCSIIrqInt
|
|
DC.L JustRTS-(*+4) ; VIA2 CB1 interrupt handler --- jASCInt
|
|
DC.L JustRTS-(*+4) ; VIA2 T2 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 T1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 "any" interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
ENDIF
|
|
|
|
|
|
IF hasDAFB THEN
|
|
|
|
IMPORT DAFBVIA2SlotInt
|
|
DAFBVIA2DT
|
|
DC.L Via2DT ; starting vector address
|
|
DC.L JustRTS-(*+4) ; VIA2 CA2 interrupt handler
|
|
DC.L DAFBVIA2SlotInt-(*+4) ; VIA2 CA1 interrupt handler --- jSlotInt
|
|
DC.L JustRTS-(*+4) ; VIA2 SR interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 CB2 interrupt handler --- jSCSIIrqInt
|
|
DC.L JustRTS-(*+4) ; VIA2 CB1 interrupt handler --- jASCInt
|
|
DC.L JustRTS-(*+4) ; VIA2 T2 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 T1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 "any" interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
; This table is provided for the InfoUnknownUnknown ProductInfo table in UniversalTables.a
|
|
; When that table goes away, this one can too...
|
|
|
|
EXPORT VIAIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (VIAIntTblEnd-VIAIntTbl)/4 ; number of entries in the table
|
|
VIAIntTbl
|
|
DC.L JustRTS-VIAIntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-VIAIntTbl ; disable interrupt sources
|
|
DC.L VIAEnableOneSecInts-VIAIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-VIAIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-VIAIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-VIAIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-VIAIntTbl ; clear sound interrupts
|
|
DC.L VIAEnableSCSIInts-VIAIntTbl ; enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-VIAIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-VIAIntTbl ; clear SCSI interrupts
|
|
DC.L VIAPowerOff-VIAIntTbl ; power off code
|
|
|
|
DC.L StdAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L StdVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
VIAIntTblEnd
|
|
|
|
|
|
IF hasRBV AND hasEgret THEN
|
|
|
|
EXPORT RBVEgretIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (RBVEgretIntTblEnd-RBVEgretIntTbl)/4 ; number of entries in the table
|
|
RBVEgretIntTbl
|
|
DC.L JustRTS-RBVEgretIntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-RBVEgretIntTbl ; disable interrupt sources
|
|
DC.L EgretEnableOneSecInts-RBVEgretIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-RBVEgretIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-RBVEgretIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-RBVEgretIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-RBVEgretIntTbl ; clear sound interrupts
|
|
DC.L JustRTS-RBVEgretIntTbl ; don't enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-RBVEgretIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-RBVEgretIntTbl ; clear SCSI interrupts
|
|
DC.L EgretPowerOff-RBVEgretIntTbl ; power off code
|
|
|
|
DC.L StdAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L RBVVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
RBVEgretIntTblEnd
|
|
|
|
ENDIF ; {hasRBV}
|
|
|
|
|
|
IF hasOrwell THEN
|
|
|
|
EXPORT Quadra700IntTbl, Quadra900IntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (Quadra700IntTblEnd-Quadra700IntTbl)/4 ; number of entries in the table
|
|
Quadra700IntTbl
|
|
DC.L JustRTS-Quadra700IntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-Quadra700IntTbl ; disable interrupt sources
|
|
DC.L VIAEnableOneSecInts-Quadra700IntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-Quadra700IntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-Quadra700IntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-Quadra700IntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-Quadra700IntTbl ; clear sound interrupts
|
|
DC.L VIAEnableSCSIInts-Quadra700IntTbl ; enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-Quadra700IntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-Quadra700IntTbl ; clear SCSI interrupts
|
|
DC.L VIAPowerOff-Quadra700IntTbl ; power off code
|
|
|
|
DC.L SONICAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L DAFBVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
Quadra700IntTblEnd
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (Quadra900IntTblEnd-Quadra900IntTbl)/4 ; number of entries in the table
|
|
Quadra900IntTbl
|
|
DC.L JustRTS-Quadra900IntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-Quadra900IntTbl ; disable interrupt sources
|
|
DC.L EgretEnableOneSecInts-Quadra900IntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-Quadra900IntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-Quadra900IntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-Quadra900IntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-Quadra900IntTbl ; clear sound interrupts
|
|
DC.L VIAEnableSCSIInts-Quadra900IntTbl ; enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-Quadra900IntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-Quadra900IntTbl ; clear SCSI interrupts
|
|
DC.L EgretPowerOff-Quadra900IntTbl ; power off code
|
|
|
|
DC.L Quadra900AutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L Quadra900VIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
Quadra900IntTblEnd
|
|
|
|
Quadra900AutoInts
|
|
DC.L AutoInt1 ; starting vector address
|
|
DC.L Level1Via1Int-(*+4) ; level 1 interrupt handler
|
|
DC.L Level2Via2Int-(*+4) ; level 2 interrupt handler
|
|
DC.L Level3SonicInt-(*+4) ; level 3 interrupt handler
|
|
DC.L Level4SccIopInt-(*+4) ; level 4 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 5 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 6 interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
Quadra900VIA2DT
|
|
DC.L Via2DT ; starting vector address
|
|
DC.L SwimIopIntVIA-(*+4) ; VIA2 CA2 interrupt handler
|
|
DC.L DAFBVIA2SlotInt-(*+4) ; VIA2 CA1 interrupt handler --- jSlotInt
|
|
DC.L JustRTS-(*+4) ; VIA2 SR interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 CB2 interrupt handler --- jSCSIIrqInt
|
|
DC.L JustRTS-(*+4) ; VIA2 CB1 interrupt handler --- jASCInt
|
|
DC.L JustRTS-(*+4) ; VIA2 T2 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 T1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 "any" interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
ENDIF ; {hasOrwell}
|
|
|
|
|
|
IF hasJaws THEN
|
|
|
|
EXPORT JawsIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (JawsIntTblEnd-JawsIntTbl)/4 ; number of entries in the table
|
|
JawsIntTbl DC.L JustRTS-JawsIntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-JawsIntTbl ; disable interrupt sources
|
|
DC.L VIAEnableOneSecInts-JawsIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-JawsIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-JawsIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-JawsIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-JawsIntTbl ; clear sound interrupts
|
|
DC.L VIAEnableSCSIInts-JawsIntTbl ; enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-JawsIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-JawsIntTbl ; clear SCSI interrupts
|
|
DC.L PMgrPowerOff-JawsIntTbl ; power off code
|
|
|
|
DC.L StdAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L StdVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
JawsIntTblEnd
|
|
|
|
ENDIF ; {hasNiagra}
|
|
|
|
|
|
IF hasNiagra THEN
|
|
|
|
EXPORT NiagraIntTbl
|
|
IMPORT NiagraVIA2SlotInt
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (NiagraIntTblEnd-NiagraIntTbl)/4 ; number of entries in the table
|
|
NiagraIntTbl
|
|
DC.L JustRTS-NiagraIntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-NiagraIntTbl ; disable interrupt sources
|
|
DC.L VIAEnableOneSecInts-NiagraIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-NiagraIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-NiagraIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-NiagraIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-NiagraIntTbl ; clear sound interrupts
|
|
DC.L VIAEnableSCSIInts-NiagraIntTbl ; enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-NiagraIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-NiagraIntTbl ; clear SCSI interrupts
|
|
DC.L PMgrPowerOff-NiagraIntTbl ; power off code
|
|
|
|
DC.L StdAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L NiagraVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
NiagraIntTblEnd
|
|
|
|
NiagraVIA2DT
|
|
DC.L Via2DT ; starting vector address
|
|
DC.L JustRTS-(*+4) ; VIA2 CA2 interrupt handler
|
|
DC.L NiagraVIA2SlotInt-(*+4) ; VIA2 CA1 interrupt handler --- jSlotInt
|
|
DC.L JustRTS-(*+4) ; VIA2 SR interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 CB2 interrupt handler --- jSCSIIrqInt
|
|
DC.L JustRTS-(*+4) ; VIA2 CB1 interrupt handler --- jASCInt
|
|
DC.L JustRTS-(*+4) ; VIA2 T2 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 T1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 "any" interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
ENDIF ; {hasNiagra}
|
|
|
|
|
|
IF hasMSC THEN
|
|
|
|
EXPORT MSCIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (MSCIntTblEnd-MSCIntTbl)/4 ; number of entries in the table
|
|
MSCIntTbl DC.L JustRTS-MSCIntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-MSCIntTbl ; disable interrupt sources
|
|
DC.L VIAEnableOneSecInts-MSCIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-MSCIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-MSCIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-MSCIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-MSCIntTbl ; clear sound interrupts
|
|
DC.L JustRTS-MSCIntTbl ; don't enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-MSCIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-MSCIntTbl ; clear SCSI interrupts
|
|
DC.L PMgrPowerOff-MSCIntTbl ; power off code
|
|
|
|
DC.L StdAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L RBVVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
MSCIntTblEnd
|
|
|
|
ENDIF ; {hasMSC}
|
|
|
|
|
|
IF hasPratt THEN
|
|
|
|
EXPORT PrattIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (PrattIntTblEnd-PrattIntTbl)/4 ; number of entries in the table
|
|
PrattIntTbl DC.L JustRTS-PrattIntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-PrattIntTbl ; disable interrupt sources
|
|
DC.L VIAEnableOneSecInts-PrattIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-PrattIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-PrattIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-PrattIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-PrattIntTbl ; clear sound interrupts
|
|
DC.L VIAEnableSCSIInts-PrattIntTbl ; don't enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-PrattIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-PrattIntTbl ; clear SCSI interrupts
|
|
DC.L PMgrPowerOff-PrattIntTbl ; power off code
|
|
|
|
DC.L StdAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L StdVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table (for now)
|
|
DC.L 0 ; end of list
|
|
PrattIntTblEnd
|
|
|
|
ENDIF ; {hasPratt}
|
|
|
|
|
|
IF hasSonora THEN
|
|
|
|
EXPORT SonoraIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (SonoraIntTblEnd-SonoraIntTbl)/4 ; number of entries in the table
|
|
SonoraIntTbl
|
|
DC.L JustRTS-SonoraIntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-SonoraIntTbl ; disable interrupt sources
|
|
DC.L EgretEnableOneSecInts-SonoraIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-SonoraIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-SonoraIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-SonoraIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-SonoraIntTbl ; clear sound interrupts
|
|
DC.L VIAEnableSCSIInts-SonoraIntTbl ; enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-SonoraIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-SonoraIntTbl ; clear SCSI interrupts
|
|
DC.L EgretPowerOff-SonoraIntTbl ; power off code
|
|
|
|
DC.L SONICAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L RBVVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
SonoraIntTblEnd
|
|
|
|
ENDIF ; {hasSonora}
|
|
|
|
|
|
IF hasDJMEMC THEN
|
|
|
|
EXPORT DJMEMCIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (DJMEMCIntTblEnd-DJMEMCIntTbl)/4 ; number of entries in the table
|
|
DJMEMCIntTbl
|
|
DC.L JustRTS-DJMEMCIntTbl ; initialization post proc routine
|
|
DC.L VIADisableIntSources-DJMEMCIntTbl ; disable interrupt sources
|
|
DC.L VIAEnableOneSecInts-DJMEMCIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-DJMEMCIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-DJMEMCIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-DJMEMCIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-DJMEMCIntTbl ; clear sound interrupts
|
|
DC.L VIAEnableSCSIInts-DJMEMCIntTbl ; enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-DJMEMCIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-DJMEMCIntTbl ; clear SCSI interrupts
|
|
DC.L VIAPowerOff-DJMEMCIntTbl ; power off code
|
|
|
|
DC.L SONICAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L DAFBVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
DJMEMCIntTblEnd
|
|
|
|
ENDIF ; {hasDJMEMC}
|
|
|
|
|
|
IF hasPSC THEN
|
|
|
|
EXPORT PSCIntTbl
|
|
IMPORT PSCVIA2SlotInt
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (PSCIntTblEnd-PSCIntTbl)/4 ; number of entries in the table
|
|
PSCIntTbl
|
|
DC.L PSCInitPostProc-PSCIntTbl ; initialization post proc routine
|
|
DC.L PSCDisableIntSources-PSCIntTbl ; disable interrupt sources
|
|
DC.L EgretEnableOneSecInts-PSCIntTbl ; enable one second interrupts
|
|
DC.L PSCEnableSlotInts-PSCIntTbl ; enable slot interrupts
|
|
DC.L JustRTS-PSCIntTbl ; enable sound interrupts
|
|
DC.L JustRTS-PSCIntTbl ; disable sound interrupts
|
|
DC.L JustRTS-PSCIntTbl ; clear sound interrupts
|
|
DC.L PSCEnableSCSIInts-PSCIntTbl ; enable SCSI interrupts
|
|
DC.L PSCDisableSCSIInts-PSCIntTbl ; disable SCSI interrupts
|
|
DC.L JustRTS-PSCIntTbl ; clear SCSI interrupts (must be cleared at source)
|
|
DC.L EgretPowerOff-PSCIntTbl ; power off code
|
|
|
|
DC.L PSCAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L PSCVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
PSCIntTblEnd
|
|
|
|
PSCAutoInts DC.L AutoInt1 ; starting vector address
|
|
DC.L Level1Via1Int-(*+4) ; level 1 interrupt handler
|
|
DC.L PSCLevel2Via2Int-(*+4) ; level 2 interrupt handler
|
|
DC.L Level3PSCInt-(*+4) ; level 3 interrupt handler
|
|
DC.L Level4PSCInt-(*+4) ; level 4 interrupt handler
|
|
DC.L Level5PSCInt-(*+4) ; level 5 interrupt handler
|
|
DC.L Level6PSCInt-(*+4) ; level 6 interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
PSCVIA2DT DC.L Via2DT ; starting vector address
|
|
DC.L JustRTS-(*+4) ; VIA2 CA2 interrupt handler
|
|
DC.L PSCVIA2SlotInt-(*+4) ; VIA2 CA1 interrupt handler --- jSlotInt
|
|
DC.L JustRTS-(*+4) ; VIA2 SR interrupt handler --- MUNI (NuBus cntrlr)
|
|
DC.L JustRTS-(*+4) ; VIA2 CB2 interrupt handler --- jSCSIIrqInt
|
|
DC.L JustRTS-(*+4) ; VIA2 CB1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 T2 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 T1 interrupt handler
|
|
DC.L JustRTS-(*+4) ; VIA2 "any" interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
ENDIF ; {hasPSC}
|
|
|
|
|
|
IF hasHMC THEN
|
|
|
|
EXPORT AMICIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (AMICIntTblEnd-AMICIntTbl)/4 ; number of entries in the table
|
|
AMICIntTbl
|
|
DC.L AMICInitPostProc-AMICIntTbl ; initialization post proc routine
|
|
DC.L AMICDisableIntSources-AMICIntTbl ; disable interrupt sources
|
|
DC.L EgretEnableOneSecInts-AMICIntTbl ; enable one second interrupts
|
|
DC.L VIAEnableSlotInts-AMICIntTbl ; enable slot interrupts
|
|
DC.L VIAEnableSoundInts-AMICIntTbl ; enable sound interrupts
|
|
DC.L VIADisableSoundInts-AMICIntTbl ; disable sound interrupts
|
|
DC.L VIAClearSoundInts-AMICIntTbl ; clear sound interrupts
|
|
DC.L JustRTS-AMICIntTbl ; don't enable SCSI interrupts
|
|
DC.L VIADisableSCSIInts-AMICIntTbl ; disable SCSI interrupts
|
|
DC.L VIAClearSCSIInts-AMICIntTbl ; clear SCSI interrupts
|
|
DC.L EgretPowerOff-AMICIntTbl ; power off code
|
|
|
|
DC.L AMICAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L RBVVIA2DT-(*+4) ; offset to VIA2 dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
AMICIntTblEnd
|
|
|
|
AMICAutoInts
|
|
DC.L AutoInt1 ; starting vector address
|
|
DC.L Level1Via1Int-(*+4) ; level 1 interrupt handler
|
|
DC.L Level2Via2Int-(*+4) ; level 2 interrupt handler
|
|
DC.L Level3AMICInt-(*+4) ; level 3 interrupt handler
|
|
DC.L Level4AMICInt-(*+4) ; level 4 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 5 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 6 interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
ENDIF ; {hasAMIC}
|
|
|
|
|
|
IF hasGrandCentral THEN
|
|
|
|
EXPORT GCIntTbl
|
|
|
|
DC.W 0 ; flags
|
|
DC.W (GCIntTblEnd-GCIntTbl)/4 ; number of entries in the table
|
|
GCIntTbl
|
|
DC.L GCInitPostProc-GCIntTbl ; initialization post proc routine
|
|
DC.L GCDisableIntSources-GCIntTbl ; disable interrupt sources
|
|
DC.L EgretEnableOneSecInts-GCIntTbl ; enable one second interrupts
|
|
DC.L JustRTS-GCIntTbl ; enable slot interrupts
|
|
DC.L GCEnableSoundInts-GCIntTbl ; enable sound interrupts
|
|
DC.L GCDisableSoundInts-GCIntTbl ; disable sound interrupts
|
|
DC.L JustRTS-GCIntTbl ; clear sound interrupts
|
|
DC.L GCEnableSCSIInts-GCIntTbl ; enable SCSI interrupts
|
|
DC.L GCDisableSCSIInts-GCIntTbl ; disable SCSI interrupts
|
|
DC.L JustRTS-GCIntTbl ; clear SCSI interrupts
|
|
DC.L EgretPowerOff-GCIntTbl ; power off code
|
|
|
|
DC.L GCAutoInts-(*+4) ; offset to interrupt vectors table
|
|
DC.L StdLvl12DT-(*+4) ; offset to level 1 and 2 dispatch vectors table
|
|
DC.L StdExtStsDT-(*+4) ; offset to secondary SCC dispatch vectors table
|
|
DC.L 0 ; end of list
|
|
GCIntTblEnd
|
|
|
|
GCAutoInts
|
|
DC.L AutoInt1 ; starting vector address
|
|
DC.L Level1Via1Int-(*+4) ; level 1 interrupt handler
|
|
DC.L Level2GCInt-(*+4) ; level 2 interrupt handler
|
|
DC.L Level3GCInt-(*+4) ; level 3 interrupt handler
|
|
DC.L Level4GCInt-(*+4) ; level 4 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 5 interrupt handler
|
|
DC.L UnusedInt-(*+4) ; level 6 interrupt handler
|
|
DC.L 0 ; end of table
|
|
|
|
ENDIF ; {hasGrandCentral}
|
|
|
|
ENDWITH ; {ProductInfo, InterruptPrims}
|
|
|
|
|
|
|
|
END
|