]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/sndsb/sndsb.h
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / sndsb / sndsb.h
1 /* WARNING: As usual for performance reasons this library generally does not
2  *          enable/disable interrupts (cli/sti). To avoid contention with
3  *          interrupt handlers the calling program should do that. */
4
5 #include <hw/cpu/cpu.h>
6 #include <stdint.h>
7
8 #define SNDSB_MAX_CARDS                         4
9
10 /* 0x2x0 + const = I/O port */
11 #define SNDSB_BIO_MIXER_INDEX                   0x4
12 #define SNDSB_BIO_MIXER_DATA                    0x5
13 #define SNDSB_BIO_DSP_RESET                     0x6
14 #define SNDSB_BIO_DSP_READ_DATA                 0xA
15 #define SNDSB_BIO_DSP_WRITE_DATA                0xC
16 #define SNDSB_BIO_DSP_WRITE_STATUS              0xC
17 #define SNDSB_BIO_DSP_READ_STATUS               0xE
18 #define SNDSB_BIO_DSP_READ_STATUS16             0xF
19
20 /* 0x3x0 + const = I/O port */
21 #define SNDSB_MPUIO_DATA                        0x0
22 #define SNDSB_MPUIO_COMMAND                     0x1
23 #define SNDSB_MPUIO_STATUS                      0x1
24
25 /* DSP versions */
26 #define SNDSB_DSPCMD_GET_VERSION                0xE1
27
28 /* MPU commands */
29 #define SNDSB_MPUCMD_RESET                      0xFF
30 #define SNDSB_MPUCMD_ENTER_UART                 0x3F
31
32 enum {
33         SNDSB_MIXER_CT1335=1,
34         SNDSB_MIXER_CT1345,             /* Sound Blaster Pro chip */
35         SNDSB_MIXER_CT1745,             /* Sound Blaster 16 */
36         SNDSB_MIXER_MAX
37 };
38
39 /* which method to use when playing audio through the DSP */
40 enum {
41         SNDSB_DSPOUTMETHOD_DIRECT=0,            /* DSP command 0x10 single-byte playback */
42         SNDSB_DSPOUTMETHOD_1xx,                 /* DSP command 0x14 8-bit mono (DSP 1.xx method) */
43         SNDSB_DSPOUTMETHOD_200,                 /* DSP command 0x1C 8-bit auto-init (DSP 2.00) */
44         SNDSB_DSPOUTMETHOD_201,                 /* DSP command 0x90 8-bit auto-init high speed (DSP 2.01+ using mixer bit to set stereo) */
45         SNDSB_DSPOUTMETHOD_3xx,                 /* DSP command 0x90 8-bit stereo auto-init (3.xx only) */
46         SNDSB_DSPOUTMETHOD_4xx,                 /* DSP command 0xBx/Cx 8/16-bit commands (DSP 4.xx) */
47         SNDSB_DSPOUTMETHOD_MAX
48 };
49
50 enum {
51         SNDSB_ESS_NONE=0,
52         SNDSB_ESS_688,
53         SNDSB_ESS_1869,
54         SNDSB_ESS_MAX
55 };
56
57 enum {
58         ADPCM_NONE=0,
59         ADPCM_4BIT,
60         ADPCM_2_6BIT,
61         ADPCM_2BIT
62 };
63
64 /* NOTES: The length is the amount of data the DSP will transfer, before signalling the ISR via the SB IRQ. Usually most programs
65  *        will set this to an even subdivision of the total buffer size e.g. so that a 32KB playback buffer signals IRQ every 8KB.
66  *        The Sound Blaster API will take care of programming the DMA controller with the physical memory address.
67  *
68  *        If auto-init or DSP 4.xx commands are used, the library will try it's best but depending on the clone hardware it cannot
69  *        guarantee that it can reprogram the physical memory address within the IRQ without causing one or two sample glitches,
70  *        i.e. that the DSP will wait up for us when we mask DMA. In an ideal world the DSP will have a FIFO so that the time we
71  *        spend DMA reprogramming is not an issue. It is said on true Creative SB16 hardware, that is precisely the case.
72  *
73  *        Because the SB library has control, it will automatically subdivide submitted buffers if playback would cross a 64KB
74  *        boundary. But, if the physical memory address is beyond the reach of your DMA controller, the library will skip your
75  *        buffer and move on. This library will provide a convenience function to check for just that.
76  *
77  *        Finally, remember that in 32-bit protected mode, linear addresses do not necessarily correspond to physical memory
78  *        addresses. The DOS extender may be running in a DPMI environment that remaps memory. You will need to provide translation
79  *        in that case. Keep in mind that when translating your linear address can be remapped in any order of physical pages, so
80  *        you cannot convert just the base and assume the rest. Don't forget also that the DPMI server and environment may very well
81  *        be paging memory to disk or otherwise moving it around. If you feed pages directly to this code, you must lock the pages.
82  *        But if you are using DOS memory, the environment will most likely translate the DMA controller for you.
83  *
84  *        In most cases, the best way to handle SB playback is to use the 8237 library to allocate a fixed DMA buffer (usually in
85  *        lower DOS memory) and loop through that buffer in fragments, filling in behind the play pointer.
86  *
87  *        the oplio variable is normally set to 0. if the Sound Blaster is Plug & Play compatible though, the OPL I/O port reported
88  *        by ISA PnP will be placed there. This means that if your program wants to use the OPL3 FM synth, it should first check
89  *        the oplio member and init the adlib library with that port. Else, it should assume port 0x388 and use that. Same rule
90  *        applies to the gameio (gameport) member.
91  *
92  *        The 'aweio' variable is meant to represent the wavetable section of
93  *        the Sound Blaster AWE32 and AWE64 cards. It will be set by the ISA PnP
94  *        code (since those cards are ISA PnP compliant) else it will be zero. */
95
96 struct sndsb_ctx {
97         uint16_t                        baseio,mpuio,oplio,gameio,aweio;
98         uint16_t                        wssio,opl3sax_controlio;
99         int8_t                          dma8,dma16,irq;
100         uint8_t                         dsp_adpcm;
101         uint8_t                         audio_data_flipped_sign;        /* DSP 4.xx command allows us to specify signed/unsigned */
102         uint8_t                         dsp_play_method;
103         uint8_t                         dsp_vmaj,dsp_vmin;
104         uint8_t                         dsp_ok,mixer_ok;
105         uint8_t                         dsp_stopping;
106         uint8_t                         mixer_chip;
107         uint8_t                         dsp_record;
108         uint8_t                         mpu_ok;
109         uint32_t                        buffer_size;            /* length of the buffer IN BYTES */
110         uint32_t                        buffer_rate;
111         uint8_t                         buffer_16bit;
112         uint8_t                         buffer_stereo;
113         uint8_t                         buffer_hispeed;
114         uint32_t                        buffer_dma_started;     /* for 1.xx modes: the DMA offset the transfer started */
115         uint32_t                        buffer_dma_started_length; /* ...and for how long */
116         volatile uint32_t               direct_dsp_io;          /* for direct DAC/ADC mode: software I/O pointer */
117         uint32_t                        buffer_irq_interval;    /* samples per IRQ. The DSP will be instructed to play this many samples, then signal the IRQ. */
118                                                                 /* ADPCM modes: This becomes "bytes per IRQ" which depending on the ADPCM encoding can be 1/2, 1/3, or 1/4 the sample count. The first ADPCM block is expected to have the reference byte. */
119                                                                 /* Sound blaster 1.0 and 2.0: Short intervals may cause playback to audibly pop and stutter, since DSP playback requires reprogramming per block */
120         volatile uint32_t               buffer_last_io;         /* EXTERNAL USE: where the calling program last wrote/read the buffer. prepare_dma sets this to zero, but program maintains it */
121         unsigned char FAR*              buffer_lin;             /* linear (program accessible pointer) */
122         uint32_t                        buffer_phys;
123         char                            dsp_copyright[128];
124         /* adjustment for known weird clones of the SB chipset */
125         uint8_t                         is_gallant_sc6600:1;    /* Reveal/Gallant SC6600: DSP v3.5 but supports SB16 commands except for the mixer register configuration stuff */
126         uint8_t                         enable_adpcm_autoinit:1;/* Most emulators including DOSBox do not emulate auto-init ADPCM playback */
127         uint8_t                         mega_em:1;              /* Gravis MEGA-EM detected, tread very very carefully */
128         uint8_t                         sbos:1;                 /* Gravis SBOS */
129         /* options for calling library */
130         uint8_t                         goldplay_mode:1;        /* Goldplay mode: Set DMA transfer length to 1 (2 if stereo) and overwrite the same region of memory from timer.
131                                                                                   An early tracker/sound library released in 1991 called Goldplay does just that, which is why
132                                                                                   stuff from the demoscene using that library has compatibility issued on today's hardware.
133                                                                                   Sick hack, huh? */
134         uint8_t                         dsp_autoinit_dma:1;     /* in most cases, you can just setup the DMA buffer to auto-init loop
135                                                                    and then re-issue the playback command as normal. But some emulations,
136                                                                    especially Gravis UltraSound SBOS/MEGA-EM, don't handle that too well.
137                                                                    the only way to play properly with them is to NOT do auto-init DMA
138                                                                    and to set the DSP block size & DMA count to only precisely the IRQ
139                                                                    interval. In which case, set this to 0 */
140         uint8_t                         dsp_autoinit_command:1; /* whether or not to use the auto-init form of playback/recording */
141         uint8_t                         dosbox_emulation:1;     /* we're running from within DOSBox */
142         uint8_t                         virtualbox_emulation:1; /* we're running from within Sun/Oracle Virtualbox */
143         uint8_t                         windows_emulation:1;    /* we're running under Windows where the implementation is probably shitty */
144         uint8_t                         windows_xp_ntvdm:1;     /* Microsoft's NTVDM.EXE based emulation in Windows XP requires some restrictive
145                                                                    workarounds to buffer size, interval, etc. to work properly. Note this also
146                                                                    applies to Windows Vista. */
147         uint8_t                         dsp_alias_port:1;       /* if set, use DSP alias I/O port 0x22D (SB DSP 1.x and 2.x only!) EMF_ID style */
148         uint8_t                         backwards:1;            /* play buffer in reverse. will instruct DMA controller to decrement addr */
149         uint8_t                         windows_9x_me_sbemul_sys:1;/* Microsoft's SBEMUL.SYS driver, Windows 98/ME */
150         uint8_t                         windows_creative_sb16_drivers:1;/* Creative Sound Blaster 16 drivers for Windows */
151         uint8_t                         vdmsound:1;             /* We're running under VDMSOUND.EXE */
152         uint8_t                         do_not_probe_irq:1;     /* if the card has known configuration registers, then do not probe */
153         uint8_t                         do_not_probe_dma:1;     /* ... */
154         uint8_t                         ess_extensions:1;       /* use ESS 688/1869 extended commands */
155         uint8_t                         force_hispeed:1;        /* always use highspeed DSP playback commands (except for DSP 4.xx) */
156         uint8_t                         dsp_4xx_fifo_autoinit:1; /* SB16 use FIFO for auto-init playback */
157         uint8_t                         dsp_4xx_fifo_single_cycle:1; /* SB16 use FIFO for single-cycle playback */
158         uint8_t                         dsp_nag_mode:1;         /* "Nag" the DSP during playback (Crystal Dream style) by reissuing playback while playback is active */
159         uint8_t                         dsp_nag_hispeed:1;      /* "Nag" even during highspeed DMA playback (NOT recommended) */
160         uint8_t                         poll_ack_when_no_irq:1; /* If playing DMA without IRQ assignment, poll the "ack" register in idle call */
161         uint8_t                         hispeed_matters:1;      /* If set, playing at rates above 22050Hz requires hispeed DSP commands */
162         uint8_t                         hispeed_blocking:1;     /* DSP does not accept commands, requires reset, in hispeed DSP playback */
163         uint8_t                         dsp_direct_dac_read_after_command;      /* read the DSP write status N times after direct DAC commands */
164         uint8_t                         dsp_direct_dac_poll_retry_timeout;      /* poll DSP write status up to N times again before attempting DSP command */
165         const char*                     reason_not_supported;   /* from last call can_do() or is_supported() */
166 /* array of mixer controls, determined by mixer chipset */
167         struct sndsb_mixer_control*     sb_mixer;
168         signed short                    sb_mixer_items;
169 /* max sample rate of the DSP */
170         unsigned short                  max_sample_rate_dsp4xx;         /* in Hz, maximum per sample frame */
171         unsigned short                  max_sample_rate_sb_hispeed;     /* in Hz, maximum per sample i.e. DSP maxes out at this value at mono, or half this value at stereo */
172         unsigned short                  max_sample_rate_sb_hispeed_rec; /* in Hz, maximum per sample i.e. DSP maxes out at this value at mono, or half this value at stereo */
173         unsigned short                  max_sample_rate_sb_play;        /* in Hz, maximum playback rate in non-hispeed mode */
174         unsigned short                  max_sample_rate_sb_rec;         /* in Hz, maximum recording rate in non-hispeed mode */
175         unsigned short                  max_sample_rate_sb_play_dac;    /* in Hz, maximum playback rate through DSP command 0x10 (Direct DAC output) */
176         unsigned short                  max_sample_rate_sb_rec_dac;     /* in Hz, maximum recording rate through DSP command 0x20 (Direct DAC input) */
177 /* function call. calling application should call this from the timer interrupt (usually IRQ 0) to
178  * allow direct DAC and "goldplay" modes to work or other idle maintenance functions. if NULL, do not call. */
179         void                            (*timer_tick_func)(struct sndsb_ctx *cx);
180 /* goldplay mode DMA buffer */
181 #if TARGET_MSDOS == 32
182         struct dma_8237_allocation*     goldplay_dma;
183 #else
184         uint8_t                         goldplay_dma[4];
185 #endif
186         uint8_t                         gold_memcpy;
187 /* ISA PnP information */
188         const char*                     pnp_name;
189         uint32_t                        pnp_id;
190         uint8_t                         pnp_csn;                                /* PnP Card Select Number */
191         uint8_t                         pnp_bios_node;                          /* PnP BIOS device node (0xFF if none) */
192         uint8_t                         ess_chipset;            /* which ESS chipset */
193 /* Windows compat hack */
194         uint16_t                        windows_creative_sb16_drivers_ver;
195         uint8_t                         windows_springwait;     /* when windows_emulation == 1, defer actually starting a DSP block until
196                                                                    the calling program has a chance to fill the buffer and check the position.
197                                                                    assume the emulation provided by Windows is the kind that (more or less)
198                                                                    directly converts DSP block commands to waveOutWrite() calls or some
199                                                                    nonsense, therefore tracking the DMA pointer and writing to the buffer
200                                                                    behind it will only cause audio glitches. Note that the test program's
201                                                                    order of calls are incompatible with Windows in this way: setting up the
202                                                                    DSP first and then setting up DMA only confuses the emulation. Doing this
203                                                                    effectively defers DSP programming until after the host program has set up
204                                                                    DMA, ensuring the minimalist emulation provided by Windows is not confused. */
205         uint8_t                         chose_autoinit_dma:1;   /* the library chooses to use autoinit DMA */
206         uint8_t                         chose_autoinit_dsp:1;   /* the library chooses to use auto-init commands */
207         uint8_t                         chose_use_dma:1;        /* the library chooses to run in a manner that uses DMA */
208         uint8_t                         direct_dac_sent_command:1;      /* direct DSP playback: we just sent the command, next is data */
209         uint8_t                         ess_extended_mode:1;    /* if set, ESS chip is in extended mode */
210         uint8_t                         timer_tick_signal:1;
211 };
212
213 /* runtime "options" that affect sound blaster probing.
214  * note that they are only advisory flags to the library.
215  * all flags are initialized to zero even prior to init_sndsb() */
216 struct sndsb_probe_opts {
217         unsigned char                   disable_manual_irq_probing:1;           /* don't use hardcore manual IRQ probing          /nomirqp */
218         unsigned char                   disable_alt_irq_probing:1;              /* don't use alt "lite" IRQ probing               /noairqp */
219         unsigned char                   disable_sb16_read_config_byte:1;        /* don't read configuration from SB16 mixer byte  /nosb16cfg */
220         unsigned char                   disable_manual_dma_probing:1;           /* don't probe for DMA channel if unknown         /nodmap */
221         unsigned char                   disable_manual_high_dma_probing:1;      /* don't probe for 16-bit DMA channel if unknown  /nohdmap */
222         unsigned char                   disable_windows_vxd_checks:1;           /* don't try to identify Windows drivers          /nowinvxd */
223         unsigned char                   disable_ess_extensions:1;               /* don't use/detect ESS688/ESS1869 commands       /noess */
224         unsigned char                   experimental_ess:1;                     /* use ESS extensions even on chips not yet supported /ex-ess */
225         unsigned char                   use_dsp_alias:1;                        /* probe, initialize and default to alias 22Dh    /sbalias:dsp */
226 };
227
228 extern struct sndsb_probe_opts          sndsb_probe_options;
229
230 #if TARGET_MSDOS == 32
231 extern signed char                      sndsb_nmi_32_hook;
232 #endif
233
234 #if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS)
235 /* TODO: This should be moved into the hw/DOS library */
236 extern unsigned char                    nmi_32_hooked;
237 extern void                             (interrupt *nmi_32_old_vec)();
238 #endif
239
240 struct sndsb_mixer_control {
241         unsigned char           index;
242         unsigned char           offset:4;
243         unsigned char           length:4;
244         const char*             name;
245 };
246
247 extern const char *sndsb_dspoutmethod_str[SNDSB_DSPOUTMETHOD_MAX];
248 extern const char *sndsb_mixer_chip_name[SNDSB_MIXER_MAX];
249 extern struct sndsb_ctx sndsb_card[SNDSB_MAX_CARDS];
250 extern signed char gallant_sc6600_map_to_dma[4];
251 extern signed char gallant_sc6600_map_to_irq[8];
252 extern const char* sndsb_adpcm_mode_str[4];
253 extern struct sndsb_ctx *sndsb_card_blaster;
254 extern int sndsb_card_next;
255
256 struct sndsb_ctx *sndsb_by_base(uint16_t x);
257 struct sndsb_ctx *sndsb_by_mpu(uint16_t x);
258 struct sndsb_ctx *sndsb_by_irq(int8_t x);
259 struct sndsb_ctx *sndsb_by_dma(uint16_t x);
260 struct sndsb_ctx *sndsb_alloc_card();
261 int init_sndsb();
262 void free_sndsb();
263 void sndsb_free_card(struct sndsb_ctx *c);
264 struct sndsb_ctx *sndsb_try_blaster_var();
265 const char *sndsb_mixer_chip_str(uint8_t c);
266 int sndsb_read_dsp(struct sndsb_ctx *cx);
267 int sndsb_read_dsp_timeout(struct sndsb_ctx *cx,unsigned long timeout_ms);
268 int sndsb_reset_dsp(struct sndsb_ctx *cx);
269 int sndsb_read_mixer(struct sndsb_ctx *cx,uint8_t i);
270 void sndsb_write_mixer(struct sndsb_ctx *cx,uint8_t i,uint8_t d);
271 int sndsb_probe_mixer(struct sndsb_ctx *cx);
272 int sndsb_mpu_command(struct sndsb_ctx *cx,uint8_t d);
273 int sndsb_mpu_write(struct sndsb_ctx *cx,uint8_t d);
274 int sndsb_mpu_read(struct sndsb_ctx *cx);
275 int sndsb_probe_mpu401(struct sndsb_ctx *cx);
276 int sndsb_write_dsp(struct sndsb_ctx *cx,uint8_t d);
277 int sndsb_write_dsp_timeout(struct sndsb_ctx *cx,uint8_t d,unsigned long timeout_ms);
278 int sndsb_write_dsp_timeconst(struct sndsb_ctx *cx,uint8_t tc);
279 int sndsb_query_dsp_version(struct sndsb_ctx *cx);
280 int sndsb_init_card(struct sndsb_ctx *cx);
281 int sndsb_try_base(uint16_t iobase);
282 int sndsb_interrupt_reason(struct sndsb_ctx *cx);
283 int sndsb_reset_mixer(struct sndsb_ctx *cx);
284 int sndsb_dsp_out_method_supported(struct sndsb_ctx *cx,unsigned long wav_sample_rate,unsigned char wav_stereo,unsigned char wav_16bit);
285 int sndsb_write_dsp_blocksize(struct sndsb_ctx *cx,uint16_t tc);
286 int sndsb_write_dsp_outrate(struct sndsb_ctx *cx,unsigned long rate);
287 uint32_t sndsb_read_dma_buffer_position(struct sndsb_ctx *cx);
288 int sndsb_shutdown_dma(struct sndsb_ctx *cx);
289 int sndsb_setup_dma(struct sndsb_ctx *cx);
290 int sndsb_prepare_dsp_playback(struct sndsb_ctx *cx,unsigned long rate,unsigned char stereo,unsigned char bit16);
291 int sndsb_begin_dsp_playback(struct sndsb_ctx *cx);
292 int sndsb_stop_dsp_playback(struct sndsb_ctx *cx);
293 void sndsb_send_buffer_again(struct sndsb_ctx *cx);
294 int sndsb_determine_ideal_dsp_play_method(struct sndsb_ctx *cx);
295 void sndsb_choose_mixer(struct sndsb_ctx *card,signed char override);
296 int sndsb_submit_buffer(struct sndsb_ctx *cx,unsigned char FAR *ptr,uint32_t phys,uint32_t len,uint32_t user,uint8_t loop);
297 int sndsb_assign_dma_buffer(struct sndsb_ctx *cx,struct dma_8237_allocation *dma);
298 unsigned char sndsb_rate_to_time_constant(struct sndsb_ctx *cx,unsigned long rate);
299 unsigned int sndsb_ess_set_extended_mode(struct sndsb_ctx *cx,int enable);
300 int sndsb_ess_read_controller(struct sndsb_ctx *cx,int reg);
301 int sndsb_ess_write_controller(struct sndsb_ctx *cx,int reg,unsigned char value);
302 void sndsb_irq_continue(struct sndsb_ctx *cx,unsigned char c);
303 unsigned int sndsb_will_dsp_nag(struct sndsb_ctx *cx);
304
305 int sb_nmi_32_auto_choose_hook();
306 #if TARGET_MSDOS == 32
307 void do_nmi_32_unhook();
308 void do_nmi_32_hook();
309 #else
310 # define do_nmi_32_unhook()
311 # define do_nmi_32_hook()
312 #endif
313
314 static inline unsigned char sndsb_ctx_to_index(struct sndsb_ctx *c) {
315         return (unsigned char)(((size_t)c - (size_t)sndsb_card) / sizeof(struct sndsb_ctx));
316 }
317
318 static inline struct sndsb_ctx *sndsb_index_to_ctx(unsigned char c) {
319         return sndsb_card + c;
320 }
321
322 static inline int sndsb_recommend_vm_wait(struct sndsb_ctx *cx) {
323         /* Microsoft Windows XP and NTVDM.EXE Sound Blaster emulation:
324          *   - Emulation is terrible. Audio can skip and stutter slightly.
325          *     Giving up your timeslice only guarantees it will stutter a lot *WORSE* */
326         if (cx->windows_emulation && cx->windows_xp_ntvdm) return 0;
327
328         /* Microsoft Windows XP and VDMSOUND. Yielding is recommended,
329          * but you will get very stuttery sound with small block sizes! */
330         if (cx->windows_emulation && cx->buffer_irq_interval < (cx->buffer_rate/4)) return 0;
331
332         /* otherwise, yes. go ahead */
333         return 1;
334 }
335
336 static inline void sndsb_interrupt_ack(struct sndsb_ctx *cx,unsigned char c) {
337         if (c & 1) inp(cx->baseio + SNDSB_BIO_DSP_READ_STATUS);
338         if (c & 2) inp(cx->baseio + SNDSB_BIO_DSP_READ_STATUS16);
339 }
340
341 static inline void sndsb_dsp_direct_output(struct sndsb_ctx *cx,unsigned char c) {
342         sndsb_write_dsp(cx,0x10);
343         sndsb_write_dsp(cx,c);
344 }
345
346 void sndsb_main_idle(struct sndsb_ctx *cx);
347
348 /* Sound Blaster ADPCM encoding routines */
349 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
350 #else
351 unsigned char sndsb_encode_adpcm_4bit(unsigned char samp);
352 unsigned char sndsb_encode_adpcm_2bit(unsigned char samp);
353 unsigned char sndsb_encode_adpcm_2_6bit(unsigned char samp,unsigned char b2);
354 void sndsb_encode_adpcm_set_reference(unsigned char c,unsigned char mode);
355 void sndsb_encode_adpcm_reset_wo_ref(unsigned char mode);
356 void sndsb_alt_lite_probe_irq(struct sndsb_ctx *cx);
357 void sndsb_manual_probe_irq(struct sndsb_ctx *cx);
358 void sndsb_manual_probe_dma(struct sndsb_ctx *cx);
359 #endif
360
361 void sndsb_write_mixer_entry(struct sndsb_ctx *sb,struct sndsb_mixer_control *mc,unsigned char nb);
362 unsigned char sndsb_read_mixer_entry(struct sndsb_ctx *sb,struct sndsb_mixer_control *mc);
363 unsigned long sndsb_real_sample_rate(struct sndsb_ctx *cx);
364
365 uint32_t sndsb_recommended_dma_buffer_size(struct sndsb_ctx *ctx,uint32_t limit);
366
367 void sndsb_timer_tick_directi_data(struct sndsb_ctx *cx);
368 void sndsb_timer_tick_directi_cmd(struct sndsb_ctx *cx);
369 void sndsb_timer_tick_directo_data(struct sndsb_ctx *cx);
370 void sndsb_timer_tick_directo_cmd(struct sndsb_ctx *cx);
371
372 const char *sndsb_ess_chipset_str(unsigned int c);
373
374 #if TARGET_MSDOS == 32
375 int sb_nmi_32_auto_choose_hook();
376 #endif
377