xref: /netbsd/sys/arch/amiga/amiga/cia.c (revision bf9ec67e)
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