1/*
2 * Copyright (c) 1992, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *
9 * All advertising materials mentioning features or use of this software
10 * must display the following acknowledgement:
11 *	This product includes software developed by the University of
12 *	California, Lawrence Berkeley Laboratory.
13 *
14 * %sccs.include.redist.c%
15 *
16 *	@(#)bsd_audiointr.s	8.1 (Berkeley) 06/11/93
17 *
18 * from: $Header: bsd_audiointr.s,v 1.6 93/04/20 21:15:08 torek Exp $ (LBL)
19 */
20
21#ifndef AUDIO_C_HANDLER
22#ifndef LOCORE
23#define LOCORE
24#endif
25#include "assym.s"
26#if BSD < 199103
27/* SunOS */
28#include <machine/intreg.h>
29#define IE_L4 IR_SOFT_INT4
30#else
31/* 4.4BSD */
32#include <sparc/sparc/intreg.h>
33/* XXX this goes in a header file -- currently, it's hidden in locore.s */
34#define INTREG_ADDR 0xf8002000
35#endif
36
37#define R_amd	%l2
38#define R_cb	%l3
39#define R_h	%l4
40#define R_t	%l5
41
42#if AUCB_SIZE > 4096
43#define MASK	%l1
44#else
45#define MASK	AUCB_SIZE - 1
46#endif
47
48	.seg	"data"
49	.align	8
50audio_savepc:
51	.word	0
52#if AUCB_SIZE > 4096
53	.word	0
54#endif
55	.seg	"text"
56	.align	4
57	.global _audio_trap
58	.global	_audio_au
59
60_audio_trap:
61#if AUCB_SIZE > 4096
62	set	audio_savepc, %l7
63	st	%l1, [%l7]
64	st	%l2, [%l7 + 4]
65	set	AUCB_SIZE - 1, %l1
66#else
67	sethi	%hi(audio_savepc), %l7
68	st	%l2, [%l7 + %lo(audio_savepc)]
69#endif
70	sethi	%hi(_audio_au), %l7
71	ld	[%l7 + %lo(_audio_au)], %l7
72	ld	[%l7 + AU_AMD], R_amd
73	add	%l7, AU_RB, R_cb		! set up read cb ptr
74	ldsb    [R_amd + AMD_IR], %g0		! clear interrupt
75	ld	[%l7 + AU_STAMP], %l6
76	inc	%l6
77	st	%l6, [%l7 + AU_STAMP]		! bump time stamp
78
79	! receive incoming data
80	ld	[R_cb + CB_HEAD], R_h
81	ld	[R_cb + CB_TAIL], R_t
82	inc	R_t
83	and	R_t, MASK, R_t
84	cmp	R_h, R_t
85	bne	2f
86	 nop
87	ld	[R_cb + CB_DROPS], %l7
88	inc	%l7
89	ba	7f
90	 st	%l7, [R_cb + CB_DROPS]
912:
92	lduh	[R_cb + CB_PAUSE], %l6
93	tst	%l6
94	be	3f
95	 nop
96	ld	[R_cb + CB_PDROPS], %l7
97	inc	%l7
98	ba	7f
99	 st	%l7, [R_cb + CB_PDROPS]
1003:
101	ldsb	[R_amd + AMD_BBRB], %l6		! get sample
102	add	R_t, CB_DATA, %l7
103	stb	%l6, [R_cb + %l7]		! store sample in buffer
104	st	R_t, [R_cb + CB_TAIL]		! update tail
1057:
106	ld	[R_cb + CB_THRESH], %l6
107	sub	R_t, R_h, %l7			! enough data?
108	and	%l7, MASK, %l7
109	cmp	%l7, %l6
110	bl	1f
111	 nop
112#if AUCB_SIZE >= 4096
113	set	AUCB_SIZE, %l7
114#else
115	mov	AUCB_SIZE, %l7
116#endif
117	st	%l7, [R_cb + CB_THRESH]		! disable threshold
118	mov	1, %l7
119	sth	%l7, [R_cb + CB_WAKING]		! set waking
120
121	sethi	%hi(INTREG_ADDR), %l7
122	ldub	[%l7 + %lo(INTREG_ADDR)], %l6
123	or	%l6, IE_L4, %l6
124	stb	%l6, [%l7 + %lo(INTREG_ADDR)]	! set software interrupt
1251:
126	/* write */
127	set	AU_WB - AU_RB, %l6		! avoid loading _audio_au ptr
128	add	R_cb, %l6, R_cb			! set up write cb ptr
129
130	ld	[R_cb + CB_HEAD], R_h
131	ld	[R_cb + CB_TAIL], R_t
132	cmp	R_h, R_t
133	bne	2f
134	 mov	0x7f, %l6			! write zero if no new data
135	ld	[R_cb + CB_DROPS], %l7
136	inc	%l7
137	ba	4f
138	 st	%l7, [R_cb + CB_DROPS]
1392:
140	lduh	[R_cb + CB_PAUSE], %l7
141	tst	%l7
142	be	3f
143	 nop
144	ld	[R_cb + CB_PDROPS], %l7
145	inc	%l7
146	ba	4f
147	 st	%l7, [R_cb + CB_PDROPS]
1483:
149	inc	R_h
150	and	R_h, MASK, R_h			! compute new head ptr
151	st	R_h, [R_cb + CB_HEAD]
152	add	R_h, CB_DATA, %l7		! adjust for struct offset
153	ldsb	[R_cb + %l7], %l6		! load sample from buffer
1544:
155	stb	%l6, [R_amd + AMD_BBTB]		! output sample to device
156	ld	[R_cb + CB_THRESH], %l6
157	sub	R_t, R_h, %l7			! test if below low water
158	and	%l7, MASK, %l7
159	cmp	%l7, %l6
160	bg	5f
161	! nop
162
163	mov	-1, %l7
164	st	%l7, [R_cb + CB_THRESH]		! disable threshold
165	sth	%l7, [R_cb + CB_WAKING]		! set waking
166
167	! set software interrupt
168	sethi	%hi(INTREG_ADDR), %l7
169	ldsb	[%l7 + %lo(INTREG_ADDR)], %l6
170	or	%l6, IE_L4, %l6
171	stb	%l6, [%l7 + %lo(INTREG_ADDR)]
1725:
173	/*
174	 * Restore psr -- note: psr delay honored by pc restore loads.
175	 */
176	mov	%l0, %psr
177#if AUCB_SIZE > 4096
178	sethi	%hi(audio_savepc), %l7
179	ldd	[%l7 + %lo(audio_savepc)], %l2
180	jmp	%l2
181	rett	%l3
182#else
183	sethi	%hi(audio_savepc), %l7
184	ld	[%l7 + %lo(audio_savepc)], %l2
185	jmp	%l1
186	rett	%l2
187#endif
188#endif
189