1 /*	MikMod sound library
2 	(c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
3 	complete list.
4 
5 	This library is free software; you can redistribute it and/or modify
6 	it under the terms of the GNU Library General Public License as
7 	published by the Free Software Foundation; either version 2 of
8 	the License, or (at your option) any later version.
9 
10 	This program is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU Library General Public License for more details.
14 
15 	You should have received a copy of the GNU Library General Public
16 	License along with this library; if not, write to the Free Software
17 	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 	02111-1307, USA.
19 */
20 
21 /*==============================================================================
22 
23   $Id$
24 
25   SoundBlaster and compatible soundcards definitions
26 
27 ==============================================================================*/
28 
29 #ifndef __DOSSB_H__
30 #define __DOSSB_H__
31 
32 #include "dosdma.h"
33 #include "dosirq.h"
34 
35 #define SB_FM_LEFT_STATUS		(sb.port + 0x00)	/* (r) Left FM status */
36 #define SB_FM_LEFT_REGSEL		(sb.port + 0x00)	/* (w) Left FM register select */
37 #define SB_FM_LEFT_DATA			(sb.port + 0x01)	/* (w) Left FM data */
38 #define SB_FM_RIGHT_STATUS		(sb.port + 0x02)	/* (r) Right FM status */
39 #define SB_FM_RIGHT_REGSEL		(sb.port + 0x02)	/* (w) Right FM register select */
40 #define SB_FM_RIGHT_DATA		(sb.port + 0x03)	/* (w) Right FM data */
41 #define SB_MIXER_REGSEL			(sb.port + 0x04)	/* (w) Mixer register select */
42 #define SB_MIXER_DATA			(sb.port + 0x05)	/* (rw)Mixer data */
43 #define SB_DSP_RESET			(sb.port + 0x06)	/* (w) DSP reset */
44 #define SB_FM_STATUS			(sb.port + 0x08)	/* (r) FM status */
45 #define SB_FM_REGSEL			(sb.port + 0x08)	/* (w) FM register select */
46 #define SB_FM_DATA			(sb.port + 0x09)	/* (w) FM data */
47 #define SB_DSP_DATA_IN			(sb.port + 0x0a)	/* (r) DSP data input */
48 #define SB_DSP_DATA_OUT			(sb.port + 0x0c)	/* (w) DSP data output */
49 #define SB_DSP_DATA_OUT_STATUS		(sb.port + 0x0c)	/* (r) DSP data output status */
50 #define SB_DSP_TIMER_IRQ		(sb.port + 0x0d)	/* (r) clear timer IRQ? */
51 #define SB_DSP_DATA_IN_STATUS		(sb.port + 0x0e)	/* (r) DSP data input status */
52 #define SB_DSP_DMA8_IRQ			(sb.port + 0x0e)	/* (r) Acknowledge 8-bit DMA transfer */
53 #define SB_DSP_DMA16_IRQ		(sb.port + 0x0f)	/* (r) Acknowledge 16-bit DMA transfer */
54 
55 /* DSP commands */
56 #define SBDSP_ASP_STATUS		0x03	/* ASP Status (SB16ASP) */
57 #define SBDSP_STATUS_OLD		0x04	/* DSP Status (Obsolete) (SB2.0-Pro2) */
58 #define SBDSP_DIRECT_DAC		0x10	/* Direct DAC, 8-bit (SB) */
59 #define SBDSP_DMA_PCM8			0x14	/* DMA DAC, 8-bit (SB) */
60 #define SBDSP_DMA_ADPCM2		0x16	/* DMA DAC, 2-bit ADPCM (SB) */
61 #define SBDSP_DMA_ADPCM2R		0x17	/* DMA DAC, 2-bit ADPCM Reference (SB) */
62 #define SBDSP_DMA_PCM8_AUTO		0x1C	/* Auto-Initialize DMA DAC, 8-bit (SB2.0) */
63 #define SBDSP_DMA_ADPCM2R_AUTO		0x1F	/* Auto-Initialize DMA DAC, 2-bit ADPCM Reference (SB2.0) */
64 #define SBDSP_DIRECT_ADC		0x20	/* Direct ADC, 8-bit (SB) */
65 #define SBDSP_DMA_ADC8			0x24	/* DMA ADC, 8-bit (SB) */
66 #define SBDSP_DIRECT_ADC8_BURST		0x28	/* Direct ADC, 8-bit (Burst) (SB-Pro2) */
67 #define SBDSP_DMA_ADC8_AUTO		0x2C	/* Auto-Initialize DMA ADC, 8-bit (SB2.0) */
68 #define SBDSP_MIDI_READ_POLL		0x30	/* MIDI Read Poll (SB) */
69 #define SBDSP_MIDI_READ_IRQ		0x31	/* MIDI Read Interrupt (SB) */
70 #define SBDSP_MIDI_READ_TIME		0x32	/* MIDI Read Timestamp Poll (SB???) */
71 #define SBDSP_MIDI_READ_TIME_IRQ	0x33	/* MIDI Read Timestamp Interrupt (SB???) */
72 #define SBDSP_MIDI_RW_POLL		0x34	/* MIDI Read Poll + Write Poll (UART) (SB2.0) */
73 #define SBDSP_MIDI_RW_IRQ		0x35	/* MIDI Read Interrupt + Write Poll (UART) (SB2.0???) */
74 #define SBDSP_MIDI_RW_TIME_IRQ		0x37	/* MIDI Read Timestamp Interrupt + Write Poll (UART) (SB2.0???) */
75 #define SBDSP_MIDI_WRITE_POLL		0x38	/* MIDI Write Poll (SB) */
76 #define SBDSP_SET_TIMING		0x40	/* Set Time Constant (SB) */
77 #define SBDSP_SET_RATE			0x41	/* Set Sample Rate, Hz (SB16) */
78 #define SBDSP_DMA_CONT8_AUTO		0x45	/* Continue Auto-Initialize DMA, 8-bit (SB16) */
79 #define SBDSP_DMA_CONT16_AUTO		0x47	/* Continue Auto-Initialize DMA, 16-bit (SB16) */
80 #define SBDSP_SET_DMA_BLOCK		0x48	/* Set DMA Block Size (SB2.0) */
81 #define SBDSP_DMA_ADPCM4		0x74	/* DMA DAC, 4-bit ADPCM (SB) */
82 #define SBDSP_DMA_ADPCM4_REF		0x75	/* DMA DAC, 4-bit ADPCM Reference (SB) */
83 #define SBDSP_DMA_ADPCM26		0x76	/* DMA DAC, 2.6-bit ADPCM (SB) */
84 #define SBDSP_DMA_ADPCM26_REF		0x77	/* DMA DAC, 2.6-bit ADPCM Reference (SB) */
85 #define SBDSP_DMA_ADPCM4R_AUTO		0x7D	/* Auto-Initialize DMA DAC, 4-bit ADPCM Reference (SB2.0) */
86 #define SBDSP_DMA_ADPCM26R_AUTO		0x7F	/* Auto-Initialize DMA DAC, 2.6-bit ADPCM Reference (SB2.0) */
87 #define SBDSP_DISABLE_DAC		0x80	/* Silence DAC (SB) */
88 #define SBDSP_HS_DMA_DAC8_AUTO		0x90	/* Auto-Initialize DMA DAC, 8-bit (High Speed) (SB2.0-Pro2) */
89 #define SBDSP_HS_DMA_ADC8_AUTO		0x98	/* Auto-Initialize DMA ADC, 8-bit (High Speed) (SB2.0-Pro2) */
90 #define SBDSP_STEREO_ADC_DIS		0xA0	/* Disable Stereo Input Mode (SBPro Only) */
91 #define SBDSP_STEREO_ADC_ENA		0xA8	/* Enable Stereo Input Mode (SBPro Only) */
92 #define SBDSP_DMA_GENERIC16		0xB0	/* Generic DAC/ADC DMA (16-bit) (SB16) */
93 #define SBDSP_DMA_GENERIC8		0xC0	/* Generic DAC/ADC DMA (8-bit) (SB16) */
94 #define SBDSP_DMA_HALT8			0xD0	/* Halt DMA Operation, 8-bit (SB) */
95 #define SBDSP_SPEAKER_ENA		0xD1	/* Enable Speaker (SB) */
96 #define SBDSP_SPEAKER_DIS		0xD3	/* Disable Speaker (SB) */
97 #define SBDSP_DMA_CONT8			0xD4	/* Continue DMA Operation, 8-bit (SB) */
98 #define SBDSP_DMA_HALT16		0xD5	/* Halt DMA Operation, 16-bit (SB16) */
99 #define SBDSP_DMA_CONT16		0xD6	/* Continue DMA Operation, 16-bit (SB16) */
100 #define SBDSP_SPEAKER_STATUS		0xD8	/* Speaker Status (SB) */
101 #define SBDSP_DMA_EXIT16_AUTO		0xD9	/* Exit Auto-Initialize DMA Operation, 16-bit (SB16) */
102 #define SBDSP_DMA_EXIT8_AUTO		0xDA	/* Exit Auto-Initialize DMA Operation, 8-bit (SB2.0) */
103 #define SBDSP_IDENTIFY			0xE0	/* DSP Identification (SB2.0) */
104 #define SBDSP_VERSION			0xE1	/* DSP Version (SB) */
105 #define SBDSP_COPYRIGHT			0xE3	/* DSP Copyright (SBPro2???) */
106 #define SBDSP_WRITE_TEST		0xE4	/* Write Test Register (SB2.0) */
107 #define SBDSP_READ_TEST			0xE8	/* Read Test Register (SB2.0) */
108 #define SBDSP_SINE_GEN			0xF0	/* Sine Generator (SB) */
109 #define SBDSP_AUX_STATUS_PRO		0xF1	/* DSP Auxiliary Status (Obsolete) (SB-Pro2) */
110 #define SBDSP_GEN_IRQ8			0xF2	/* IRQ Request, 8-bit (SB) */
111 #define SBDSP_GEN_IRQ16			0xF3	/* IRQ Request, 16-bit (SB16) */
112 #define SBDSP_STATUS			0xFB	/* DSP Status (SB16) */
113 #define SBDSP_AUX_STATUS_16		0xFC	/* DSP Auxiliary Status (SB16) */
114 #define SBDSP_CMD_STATUS		0xFD	/* DSP Command Status (SB16) */
115 
116 /* Mixer commands */
117 #define SBMIX_RESET			0x00	/* Reset                        Write       SBPro */
118 #define SBMIX_STATUS			0x01	/* Status                       Read        SBPro */
119 #define SBMIX_MASTER_LEVEL1		0x02	/* Master Volume                Read/Write  SBPro Only */
120 #define SBMIX_DAC_LEVEL			0x04	/* DAC Level                    Read/Write  SBPro */
121 #define SBMIX_FM_OUTPUT			0x06	/* FM Output Control            Read/Write  SBPro Only */
122 #define SBMIX_MIC_LEVEL			0x0A	/* Microphone Level             Read/Write  SBPro */
123 #define SBMIX_INPUT_SELECT		0x0C	/* Input/Filter Select          Read/Write  SBPro Only */
124 #define SBMIX_OUTPUT_SELECT		0x0E	/* Output/Stereo Select         Read/Write  SBPro Only */
125 #define SBMIX_FM_LEVEL			0x22	/* Master Volume                Read/Write  SBPro */
126 #define SBMIX_MASTER_LEVEL		0x26	/* FM Level                     Read/Write  SBPro */
127 #define SBMIX_CD_LEVEL			0x28	/* CD Audio Level               Read/Write  SBPro */
128 #define SBMIX_LINEIN_LEVEL		0x2E	/* Line In Level                Read/Write  SBPro */
129 #define SBMIX_MASTER_LEVEL_L		0x30	/* Master Volume Left           Read/Write  SB16 */
130 #define SBMIX_MASTER_LEVEL_R		0x31	/* Master Volume Right          Read/Write  SB16 */
131 #define SBMIX_DAC_LEVEL_L		0x32	/* DAC Level Left               Read/Write  SB16 */
132 #define SBMIX_DAC_LEVEL_R		0x33	/* DAC Level Right              Read/Write  SB16 */
133 #define SBMIX_FM_LEVEL_L		0x34	/* FM Level Left                Read/Write  SB16 */
134 #define SBMIX_FM_LEVEL_R		0x35	/* FM Level Right               Read/Write  SB16 */
135 #define SBMIX_CD_LEVEL_L		0x36	/* CD Audio Level Left          Read/Write  SB16 */
136 #define SBMIX_CD_LEVEL_R		0x37	/* CD Audio Level Right         Read/Write  SB16 */
137 #define SBMIX_LINEIN_LEVEL_L		0x38	/* Line In Level Left           Read/Write  SB16 */
138 #define SBMIX_LINEIN_LEVEL_R		0x39	/* Line In Level Right          Read/Write  SB16 */
139 #define SBMIX_MIC_LEVEL_16		0x3A	/* Microphone Level             Read/Write  SB16 */
140 #define SBMIX_PCSPK_LEVEL		0x3B	/* PC Speaker Level             Read/Write  SB16 */
141 #define SBMIX_OUTPUT_CONTROL		0x3C	/* Output Control               Read/Write  SB16 */
142 #define SBMIX_INPUT_CONTROL_L		0x3D	/* Input Control Left           Read/Write  SB16 */
143 #define SBMIX_INPUT_CONTROL_R		0x3E	/* Input Control Right          Read/Write  SB16 */
144 #define SBMIX_INPUT_GAIN_L		0x3F	/* Input Gain Control Left      Read/Write  SB16 */
145 #define SBMIX_INPUT_GAIN_R		0x40	/* Input Gain Control Right     Read/Write  SB16 */
146 #define SBMIX_OUTPUT_GAIN_L		0x41	/* Output Gain Control Left     Read/Write  SB16 */
147 #define SBMIX_OUTPUT_GAIN_R		0x42	/* Output Gain Control Right    Read/Write  SB16 */
148 #define SBMIX_AGC_CONTROL		0x43	/* Automatic Gain Control (AGC) Read/Write  SB16 */
149 #define SBMIX_TREBLE_L			0x44	/* Treble Left                  Read/Write  SB16 */
150 #define SBMIX_TREBLE_R			0x45	/* Treble Right                 Read/Write  SB16 */
151 #define SBMIX_BASS_L			0x46	/* Bass Left                    Read/Write  SB16 */
152 #define SBMIX_BASS_R			0x47	/* Bass Right                   Read/Write  SB16 */
153 #define SBMIX_IRQ_SELECT		0x80	/* IRQ Select                   Read/Write  SB16 */
154 #define SBMIX_DMA_SELECT		0x81	/* DMA Select                   Read/Write  SB16 */
155 #define SBMIX_IRQ_STATUS		0x82	/* IRQ Status                   Read        SB16 */
156 
157 /* SB_DSP_DATA_OUT_STATUS and SB_DSP_DATA_IN_STATUS bits */
158 #define SBM_DSP_READY			0x80
159 
160 /* SB_DSP_RESET / SBMIX_RESET */
161 #define SBM_DSP_RESET			0x01
162 
163 /* SBMIX_OUTPUT_SELECT */
164 #define SBM_MIX_STEREO			0x02
165 #define SBM_MIX_FILTER			0x20
166 
167 /* SBDSP_DMA_GENERIC16/SBDSP_DMA_GENERIC8 */
168 #define SBM_GENDAC_FIFO			0x02
169 #define SBM_GENDAC_AUTOINIT		0x04
170 #define SBM_GENDAC_ADC			0x08
171 /* Second (mode) byte */
172 #define SBM_GENDAC_SIGNED		0x10
173 #define SBM_GENDAC_STEREO		0x20
174 
175 /* DSP version masks */
176 #define SBVER_10			0x0100	/* Original SoundBlaster */
177 #define SBVER_15			0x0105	/* SoundBlaster 1.5 */
178 #define SBVER_20			0x0200	/* SoundBlaster 2.0 */
179 #define SBVER_PRO			0x0300	/* SoundBlaster Pro */
180 #define SBVER_PRO2			0x0301	/* SoundBlaster Pro 2 */
181 #define SBVER_16			0x0400	/* SoundBlaster 16 */
182 #define SBVER_AWE32			0x040c	/* SoundBlaster AWE32 */
183 
184 typedef unsigned char boolean;
185 
186 #ifndef FALSE
187 #define FALSE				0
188 #define TRUE				1
189 #endif
190 
191 /* Play mode bits */
192 #define SBMODE_16BITS			0x0001
193 #define SBMODE_STEREO			0x0002
194 #define SBMODE_SIGNED			0x0004
195 
196 /* Mask for capabilities that never change */
197 #define SBMODE_MASK			(SBMODE_16BITS | SBMODE_STEREO)
198 
199 /* You can fill some members of this struct (i.e. port,irq,dma) before
200  * calling sb_detect() or sb_open()... this will ignore environment settings.
201  */
202 typedef struct __sb_state_s {
203 	boolean ok;			/* Are structure contents valid? */
204 	int port, aweport;		/* sb/awe32 base port */
205 	int irq;			/* SoundBlaster IRQ */
206 	int dma8, dma16;		/* 8-bit and 16-bit DMAs */
207 	int maxfreq_mono;		/* Maximum discretization frequency / mono mode */
208 	int maxfreq_stereo;		/* Maximum discretization frequency / stereo mode */
209 	unsigned short dspver;		/* DSP version number */
210 	struct irq_handle *irq_handle;	/* The interrupt handler */
211 	dma_buffer *dma_buff;		/* Pre-allocated DMA buffer */
212 	unsigned char caps;		/* SoundBlaster capabilities (SBMODE_XXX) */
213 	unsigned char mode;		/* Current SB mode (SBMODE_XXX) */
214 	boolean open;			/* Whenever the card has been opened */
215 	volatile int irqcount;		/* Incremented on each IRQ... for diagnostics */
216 	void (*timer_callback) ();	/* Called TWICE per buffer play */
217 } __sb_state;
218 
219 extern __sb_state sb;
220 
221 extern void __sb_wait();
222 
__sb_dsp_ready_in()223 static inline boolean __sb_dsp_ready_in()
224 {
225 	int count;
226 	for (count = 10000; count >= 0; count--)
227 		if (inportb(SB_DSP_DATA_IN_STATUS) & SBM_DSP_READY)
228 			return TRUE;
229 	return FALSE;
230 }
231 
__sb_dsp_ready_out()232 static inline boolean __sb_dsp_ready_out()
233 {
234 	int count;
235 	for (count = 10000; count >= 0; count--)
236 		if ((inportb(SB_DSP_DATA_OUT_STATUS) & SBM_DSP_READY) == 0)
237 			return TRUE;
238 	return FALSE;
239 }
240 
__sb_dsp_out(unsigned char reg)241 static inline void __sb_dsp_out(unsigned char reg)
242 {
243 	__sb_dsp_ready_out();
244 	outportb(SB_DSP_DATA_OUT, reg);
245 }
246 
__sb_dsp_in()247 static inline unsigned char __sb_dsp_in()
248 {
249 	__sb_dsp_ready_in();
250 	return inportb(SB_DSP_DATA_IN);
251 }
252 
__sb_dspreg_out(unsigned char reg,unsigned char val)253 static inline void __sb_dspreg_out(unsigned char reg, unsigned char val)
254 {
255 	__sb_dsp_out(reg);
256 	__sb_dsp_out(val);
257 }
258 
__sb_dspreg_outwlh(unsigned char reg,unsigned short val)259 static inline void __sb_dspreg_outwlh(unsigned char reg, unsigned short val)
260 {
261 	__sb_dsp_out(reg);
262 	__sb_dsp_out(val);
263 	__sb_dsp_out(val >> 8);
264 }
265 
__sb_dspreg_outwhl(unsigned char reg,unsigned short val)266 static inline void __sb_dspreg_outwhl(unsigned char reg, unsigned short val)
267 {
268 	__sb_dsp_out(reg);
269 	__sb_dsp_out(val >> 8);
270 	__sb_dsp_out(val);
271 }
272 
__sb_dspreg_in(unsigned char reg)273 static inline unsigned char __sb_dspreg_in(unsigned char reg)
274 {
275 	__sb_dsp_out(reg);
276 	return __sb_dsp_in();
277 }
278 
__sb_dsp_ack_dma8()279 static inline void __sb_dsp_ack_dma8()
280 {
281 	inportb(SB_DSP_DMA8_IRQ);
282 }
283 
__sb_dsp_ack_dma16()284 static inline void __sb_dsp_ack_dma16()
285 {
286 	inportb(SB_DSP_DMA16_IRQ);
287 }
288 
__sb_dsp_version()289 static inline unsigned short __sb_dsp_version()
290 {
291 	unsigned short ver;
292 	__sb_dsp_out(SBDSP_VERSION);
293 	__sb_dsp_ready_in();
294 	ver = ((unsigned short)__sb_dsp_in()) << 8;
295 	ver |= __sb_dsp_in();
296 	return ver;
297 }
298 
__sb_mixer_out(unsigned char reg,unsigned char val)299 static inline void __sb_mixer_out(unsigned char reg, unsigned char val)
300 {
301 	outportb(SB_MIXER_REGSEL, reg);
302 	outportb(SB_MIXER_DATA, val);
303 }
304 
__sb_mixer_in(unsigned char reg)305 static inline unsigned char __sb_mixer_in(unsigned char reg)
306 {
307 	outportb(SB_MIXER_REGSEL, reg);
308 	return inportb(SB_MIXER_DATA);
309 }
310 
311 /* Enable stereo transfers: sbpro mode only */
__sb_stereo(boolean stereo)312 static inline void __sb_stereo(boolean stereo)
313 {
314 	unsigned char val = __sb_mixer_in(SBMIX_OUTPUT_SELECT);
315 	if (stereo)
316 		val |= SBM_MIX_STEREO;
317 	else
318 		val &= ~SBM_MIX_STEREO;
319 	__sb_mixer_out(SBMIX_OUTPUT_SELECT, val);
320 }
321 
322 /* Detect whenever SoundBlaster is present and fill "sb" structure */
323 extern boolean sb_detect();
324 /* Reset SoundBlaster */
325 extern void sb_reset();
326 /* Start working with SoundBlaster */
327 extern boolean sb_open();
328 /* Finish working with SoundBlaster */
329 extern boolean sb_close();
330 /* Enable/disable speaker output */
331 extern void sb_output(boolean enable);
332 /* Start playing from DMA buffer in either 8/16 bit mono/stereo */
333 extern boolean sb_start_dma(unsigned char mode, unsigned int freq);
334 /* Stop playing from DMA buffer */
335 extern void sb_stop_dma();
336 /* Query current position/total size of the DMA buffer */
337 extern void sb_query_dma(unsigned int *dma_size, unsigned int *dma_pos);
338 
339 #endif /* __DOSSB_H__ */
340 
341 /* ex:set ts=4: */
342