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