initial import
[dosrtxon] / libs / mikmod / drivers / dos / dossb.h
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
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
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
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
247 static inline unsigned char __sb_dsp_in()
248 {
249         __sb_dsp_ready_in();
250         return inportb(SB_DSP_DATA_IN);
251 }
252
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
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
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
273 static inline unsigned char __sb_dspreg_in(unsigned char reg)
274 {
275         __sb_dsp_out(reg);
276         return __sb_dsp_in();
277 }
278
279 static inline void __sb_dsp_ack_dma8()
280 {
281         inportb(SB_DSP_DMA8_IRQ);
282 }
283
284 static inline void __sb_dsp_ack_dma16()
285 {
286         inportb(SB_DSP_DMA16_IRQ);
287 }
288
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
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
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 */
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: */