Home | History | Annotate | Line # | Download | only in amiga
      1 /*	$NetBSD: cia.c,v 1.12 2009/03/18 10:22:23 cegger Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1993 Markus Wild
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *      This product includes software developed by Markus Wild.
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 /*
     33  *  this file provides an interface to CIA-generated interrupts.
     34  *  Since the interrupt control register of a CIA is cleared
     35  *  when it's read, it is essential that different interrupt
     36  *  sources are managed from one central handler, or interrupts
     37  *  can get lost.
     38  *
     39  *  if you write a handler dealing with a yet unused interrupt
     40  *  bit (handler == not_used), enter your interrupt handler
     41  *  in the appropriate table below. If your handler must poll
     42  *  for an interrupt flag to come active, *always* call
     43  *  dispatch_cia_ints() afterwards with bits in the mask
     44  *  register your code didn't already deal with.
     45  */
     46 
     47 #include <sys/cdefs.h>
     48 __KERNEL_RCSID(0, "$NetBSD: cia.c,v 1.12 2009/03/18 10:22:23 cegger Exp $");
     49 
     50 #include <sys/types.h>
     51 #include <amiga/amiga/cia.h>
     52 #include "par.h"
     53 #include "kbd.h"
     54 
     55 struct cia_intr_dispatch {
     56   u_char	mask;
     57   void		(*handler)(int);
     58 };
     59 
     60 vaddr_t CIAAbase, CIABbase, CIAADDR;
     61 
     62 static void not_used(int);
     63 void kbdintr(int);
     64 void parintr(int);
     65 
     66 /* handlers for CIA-A (IPL-2) */
     67 static struct cia_intr_dispatch ciaa_ints[] = {
     68 	{ CIA_ICR_TA,		not_used },
     69 	{ CIA_ICR_TB,		not_used },
     70 	{ CIA_ICR_ALARM,	not_used },
     71 #if NKBD > 0
     72 	{ CIA_ICR_SP,	kbdintr },
     73 #else
     74 	{ CIA_ICR_SP,	not_used },
     75 #endif
     76 #if NPAR > 0
     77 	{ CIA_ICR_FLG,	parintr },
     78 #else
     79 	{ CIA_ICR_FLG,	not_used },
     80 #endif
     81 	{ 0,		0 },
     82 };
     83 
     84 /* handlers for CIA-B (IPL-6) */
     85 static struct cia_intr_dispatch ciab_ints[] = {
     86 	{ CIA_ICR_TA,	not_used },	/* used directly in locore.s */
     87 	{ CIA_ICR_TB,	not_used },	/* "" */
     88 	{ CIA_ICR_ALARM,	not_used },
     89 	{ CIA_ICR_SP,	not_used },
     90 	{ CIA_ICR_FLG,	not_used },
     91 	{ 0,		0 },
     92 };
     93 
     94 
     95 
     96 void
     97 dispatch_cia_ints(int which, int mask)
     98 {
     99 	struct cia_intr_dispatch *disp;
    100 
    101 	disp = (which == 0) ? ciaa_ints : ciab_ints;
    102 
    103 	for (;disp->mask; disp++)
    104 		if (mask & disp->mask)
    105 			disp->handler(disp->mask);
    106 }
    107 
    108 void
    109 ciaa_intr(void)
    110 {
    111 	dispatch_cia_ints (0, ciaa.icr);
    112 }
    113 
    114 /*
    115  * NOTE: ciab_intr() is *not* currently called. If you want to support
    116  * the FLG interrupt, which is used to indicate a disk-index
    117  * interrupt, you'll have to hack a call to ciab_intr() into
    118  * the lev6 interrupt handler in locore.s !
    119  */
    120 void
    121 ciab_intr(void)
    122 {
    123 	dispatch_cia_ints (1, ciab.icr);
    124 }
    125 
    126 
    127 static void
    128 not_used (int mask)
    129 {
    130 }
    131