mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 01:49:19 +00:00
3134 lines
136 KiB
Plaintext
3134 lines
136 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
|