; ; Hacks to match MacOS (most recent first): ; ; 8/3/92 Elliot make this change ; 9/2/94 SuperMario ROM source dump (header preserved below) ; ; ; 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): ; ; 1/11/94 GS Enabled NMI in Grand Central on TNT. ; 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ ; machines. ; 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: ) ; 11/10/93 fau Update from SuperMunggio . Also, addeb back KW's ; checkin. ; 10/20/93 fau Enabled the PowerOff and One-secs interrupts for GrandCentral. ; 9/22/93 chp The Grand Central interrupt handler registration macros ; underwent an interface change. ; 9/13/93 chp Enable VIA interrupts after initializing the interrupt ; dispatcher, and enable only SCSI0 interrupts for the time being. ; 8/26/93 chp Use the provided interrupt dispatch table maintenance macros in ; within the Grand Central interrupt initialization postproc. ; 8/25/93 chp Introduce Grand Central support for TNT. ; 11/10/93 rab Added semicolon to last checkin comment so the build ; wouldn't barf… ; 11/10/93 SAM Roll in from mc900ftjesus. ; 11/10/93 SAM Disable sound in/out DMA in AMICInitPostProc. ; 11/9/93 KW added some eieioSTP macros. Only expands for CygnusX1 ROM ; 10/29/93 pdw Moved intRegs and intRegsSize out of here and into ; SysPrivateEqu.a since SCSI Manager 4.3 is now using them. ; 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. ; 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. ; 9/10/93 pdw Pulled the SCC Level 4 interrupt vectors and refcons out of the ; DMA Dispatch table (just like the maceVector). ; 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. ; 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). ; 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. ; 9/2/93 SKH StdVIA2DT always needs to be defined, because the universal code ; needs it. ; 8/21/93 chp Reduced the PDMDMAHndlr instruction count by 30%. ; 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. ; 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. ; 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. ; 8/1/93 pdw Fixed 50/50 AMIC/SCSI problem by avoiding the dangerous SCSI ; speed value of 3 (11 in 2 speed bits). ; 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. ; 7/1/93 KW Roll in from LW. In PSCInitPostProc took out installation of ; muni nubus control int. handler. Also removed MuniVia2Int ; 6/14/93 kc Roll in Ludwig. ; 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. ; 5/25/93 SAM Added some Supports24Bit condos around ServiceIntMMU. ; 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. ; 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. ; 4/22/93 CSS Changed emDMADispGlobs to emDMADispatchGlobals which matches ; Reality. ; 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. ; 4/5/93 RC Changed the DMA interrupts to Level 4 on PDM and added the SCC ; interrupt handleing to the DMA handler. ; 4/2/93 GMR Added a couple of nop's to PDMDMAHndlr to synchronize I/O. ; 4/1/93 GMR Moved PDM's DMA stuff from StartInit to here, where it belongs. ; 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. ; 1/20/93 PN Bring over the fix for PSCL5Interrupt from Ludwig where A4 value ; is trashed after 1st time through the loop. ; 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. ; 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). ; 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. ; 12/1/92 EH Added interrupt table for Pratt. ; 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". ; 11/20/92 fau Added a MUNI interrupt handler for Cyclone. ; 11/16/92 rab Roll in Horror changes (see H7 comments below) ; 11/4/92 fau Backed out change in 'cause we found what the real ; culprit was (somebody writing to a ROM address that was at that ; table!) ; 11/3/92 RB Do not "fall-into" ServiceIntMMU, since that defeats automatic ; vector patching schemes. ; 11/3/92 SWC Changed ShutdownEqu.a->Shutdown.a. ; 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. ; 10/21/92 fau Changed all MMCExists to PSCExists. ; 10/7/92 mal Changed Cyclone L3,4,5,6 interrupt dispatchers to check for a ; "later" interrupt. ; 9/28/92 RB Fix PowerOff on Quadra 900 & 950 by updating the Egret check in ; the PowerOff trap. ; 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) ; 8/26/92 kc Fix compiler warning. ; 8/24/92 PN Take out checkEVT1 code ; 8/17/92 CCH Changed “TestFor” of OrwellExists to OrwellDecoder. ; 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. ; 6/30/92 kc Rename EclipseVia2SlotInt to DAFBVia2SlotInt. Move SlotInterrupt ; handlers from InterruptHandlers.a. ; 6/22/92 mal Changed priority of PSCL4Interrupt to SCCB, SCCA, Sound, then ; DMA ints. ; 6/21/92 PN Rollin PatchIIciROM.a and fix the through put problem on Apollo ; and TimLC ; 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. ; 6/20/92 mal (RB) Made ASC routines do nothing on Cyclone. ; 5/28/92 RB When I rolled in Cyclone, I forgot to add one more patch rollin ; from Horror. So it is now in. ; 5/24/92 RB Added PSC interrupt handlers from the Pandora file ; InterruptHandlersPatch.a PSCLxDispatch routines. ; 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. ; 5/17/92 kc Include PowerPrivEqu.a and add "pmCommandRec." ; 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. ; 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. ; 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. ; 2/11/92 GS Add patch in Power Switch Int handler to enable Soft Power Off. Patch ; code (PowerSwitchIntPatch) is located in EgretPatchesToo.a. ; 2/7/92 mal Updated references to RBV VIA2 IER & IFR to PSC VIA2 IER & IFR offsets. ; 1/24/92 mal Added PSCIntInstall back in. Changed DisableIntSources to use correct ; VIA2 IER offset for Cyclone. ; 1/22/92 RMP (for mal) Commented PSCINTINSTALL out. ; 1/21/92 mal Added patches to support PSC interrupt dispatchers for levels 3,4,5,&6. ;

12/20/91 JC Use common Via2/RBV offset equates. ;

8/13/91 SWC Fixed the revision numbers in the comments to reflect the HORROR ; numbering scheme instead of my own. ;

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… ; 1/22/88 rwh Fixed Lvl5Int - needed to pop return addr off stack for bypass ; ints. <1.6> ; 12/18/87 ggd Changed polarity of slot interrupt bits for MvMac. <1.6> ; 12/17/87 MSH Added deferred task stuff for Laguna and clock speed support ; too. ; 11/3/87 rwh Roll in PB231: Fix deferred task dispatcher to dequeue task ; BEFORE calling it ; 10/29/87 rwh Port to Modern Victorian ; 9/30/87 MSH Port to HcMac (Laguna) ; 4/20/87 RDC Rolled in patch from ROM78Fix for poweroff routine ; 2/13/87 RDC Add hook in deferred task routine for posterity ; 2/12/87 RDC Fix bug that allows deferred tasks to override VBL tasks ; 1/27/87 RDC Add fix to protect level 1 interrupts more globally from 32-bit ; mode. Deleted check in VBL handlers. ; 1/26/87 RDC Added various bug fixes ; 1/25/87 RDC Code review cleanup ; 1/2/87 RDC Remove MMU mode swap when dispatching to slot interrupt ; routines, add misc cleanup ; 12/19/86 FJL Changed NumSlots to sNumSlots for GWN. ; 12/9/86 JSP Added testing and use of MMU mode swapping to levels 1,2, and 4. ; 12/7/86 RDC Added deferred task support, cleaned up comments ; 11/11/86 RDC Another bug fix in interrupt handler for slot priority ; 11/10/86 RDC Fixed bug in interrupt handler for slot priority ; 11/2/86 RDC Finally added the copyright notice! ; 10/24/86 CSL Took out one autopoll per VBL for mouse data update. ; 10/18/86 RDC Added fix to SlotVBLInt to leave interrupts disabled for now ; 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 ; 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. ; 10/3/86 CSL Set one autopoll per VBL for mouse data update. Fixed in Kbd.a ; and Crsrcore.a. Changed include files ; 8/20/86 RDC Added change to NuMac slot interrupt handler to fix problem of ; missing slot interrupts ; 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. ; 8/7/86 RDC Added comment changes for new NuMac hardware (VIA2 interrupt ; changes) ; 8/2/86 RDC Added fix for handling multiple slot interrupts ; 8/1/86 WRL Skip jCrsrTask in VBL handler if it's NIL. ; 7/29/86 RDC deleted video interrupt handler - now on video cards ; 7/28/86 RDC Added changes for handling NuMac slot interrupts. ; 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 ; 6/24/86 RDC Added debounce loop to NuMac poweroff int handler ; 6/17/86 RDC Fixed bug in NuMac poweroff int handler ; 6/11/86 RDC Added interrupt handler for NuMac poweroff interrupt ; 5/30/86 CSL Added changes for Aladdin, and Aladdin Front desk bus support. ; 5/21/86 RDC Fixed slot interrupt dispatcher to check for interrupts from all ; slots before exiting ; 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 IntRegs reg a0-a3/d0-d3 ; registers saved by all interrupt handlers IntRegsSize equ 8*4 ; size of IntRegs in bytes - must change if IntRegs changes! ; if this changes, then you must update HALc96Routines.a to handle ; both old and new cases. 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< 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< MOVE.L SP,-(SP) ; pmRBuffer (not used)

MOVE.L (SP),-(SP) ; pmSBuffer (the sleep signature)

MOVE.W #4,-(SP) ; pmLength = 4

MOVE.W #PmgrPWRoff,-(SP) ; pmCommand = power off

MOVE.L SP,A0 ; point to the parameter block

_PmgrOp ; power off using the PMGR

LEA pmRBuffer+4+4(SP),SP; clean up the stack

BNE.S @callSleep ; -> the call failed, so we have an old PMGR

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< 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 BCLR.B #7,$50F14011 ; Disable Sound Input ; 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 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< 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 @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< 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< 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