1 /* $NetBSD: cia.c,v 1.9 2002/04/25 09:20:27 aymeric 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.9 2002/04/25 09:20:27 aymeric 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(which, mask) 98 int which; 99 int mask; 100 { 101 struct cia_intr_dispatch *disp; 102 103 disp = (which == 0) ? ciaa_ints : ciab_ints; 104 105 for (;disp->mask; disp++) 106 if (mask & disp->mask) 107 disp->handler(disp->mask); 108 } 109 110 void 111 ciaa_intr() 112 { 113 dispatch_cia_ints (0, ciaa.icr); 114 } 115 116 /* 117 * NOTE: ciab_intr() is *not* currently called. If you want to support 118 * the FLG interrupt, which is used to indicate a disk-index 119 * interrupt, you'll have to hack a call to ciab_intr() into 120 * the lev6 interrupt handler in locore.s ! 121 */ 122 void 123 ciab_intr() 124 { 125 dispatch_cia_ints (1, ciab.icr); 126 } 127 128 129 static void 130 not_used (mask) 131 int mask; 132 { 133 } 134