Statistics
| Branch: | Revision:

root / hw / sb16.c @ 87ecb68b

History | View | Annotate | Download (35.8 kB)

1 27503323 bellard
/*
2 27503323 bellard
 * QEMU Soundblaster 16 emulation
3 1d14ffa9 bellard
 *
4 1d14ffa9 bellard
 * Copyright (c) 2003-2005 Vassili Karpov (malc)
5 1d14ffa9 bellard
 *
6 27503323 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 27503323 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 27503323 bellard
 * in the Software without restriction, including without limitation the rights
9 27503323 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 27503323 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 27503323 bellard
 * furnished to do so, subject to the following conditions:
12 27503323 bellard
 *
13 27503323 bellard
 * The above copyright notice and this permission notice shall be included in
14 27503323 bellard
 * all copies or substantial portions of the Software.
15 27503323 bellard
 *
16 27503323 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 27503323 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 27503323 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 27503323 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 27503323 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 27503323 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 27503323 bellard
 * THE SOFTWARE.
23 27503323 bellard
 */
24 87ecb68b pbrook
#include "hw.h"
25 87ecb68b pbrook
#include "audiodev.h"
26 87ecb68b pbrook
#include "audio/audio.h"
27 87ecb68b pbrook
#include "isa.h"
28 87ecb68b pbrook
#include "qemu-timer.h"
29 27503323 bellard
30 85571bc7 bellard
#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
31 d75d9f6b bellard
32 fb065187 bellard
#define dolog(...) AUD_log ("sb16", __VA_ARGS__)
33 15b61470 bellard
34 15b61470 bellard
/* #define DEBUG */
35 15b61470 bellard
/* #define DEBUG_SB16_MOST */
36 15b61470 bellard
37 fb065187 bellard
#ifdef DEBUG
38 fb065187 bellard
#define ldebug(...) dolog (__VA_ARGS__)
39 fb065187 bellard
#else
40 fb065187 bellard
#define ldebug(...)
41 fb065187 bellard
#endif
42 fb065187 bellard
43 85571bc7 bellard
#define IO_READ_PROTO(name)                             \
44 7d977de7 bellard
    uint32_t name (void *opaque, uint32_t nport)
45 85571bc7 bellard
#define IO_WRITE_PROTO(name)                                    \
46 7d977de7 bellard
    void name (void *opaque, uint32_t nport, uint32_t val)
47 27503323 bellard
48 85571bc7 bellard
static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
49 d329a6fb bellard
50 27503323 bellard
static struct {
51 27503323 bellard
    int ver_lo;
52 27503323 bellard
    int ver_hi;
53 27503323 bellard
    int irq;
54 27503323 bellard
    int dma;
55 27503323 bellard
    int hdma;
56 27503323 bellard
    int port;
57 85571bc7 bellard
} conf = {5, 4, 5, 1, 5, 0x220};
58 27503323 bellard
59 5e2a6443 bellard
typedef struct SB16State {
60 c0fe3827 bellard
    QEMUSoundCard card;
61 d537cf6c pbrook
    qemu_irq *pic;
62 85571bc7 bellard
    int irq;
63 85571bc7 bellard
    int dma;
64 85571bc7 bellard
    int hdma;
65 85571bc7 bellard
    int port;
66 85571bc7 bellard
    int ver;
67 85571bc7 bellard
68 27503323 bellard
    int in_index;
69 27503323 bellard
    int out_data_len;
70 27503323 bellard
    int fmt_stereo;
71 27503323 bellard
    int fmt_signed;
72 27503323 bellard
    int fmt_bits;
73 85571bc7 bellard
    audfmt_e fmt;
74 27503323 bellard
    int dma_auto;
75 85571bc7 bellard
    int block_size;
76 27503323 bellard
    int fifo;
77 27503323 bellard
    int freq;
78 27503323 bellard
    int time_const;
79 27503323 bellard
    int speaker;
80 27503323 bellard
    int needed_bytes;
81 27503323 bellard
    int cmd;
82 27503323 bellard
    int use_hdma;
83 85571bc7 bellard
    int highspeed;
84 85571bc7 bellard
    int can_write;
85 27503323 bellard
86 27503323 bellard
    int v2x6;
87 27503323 bellard
88 85571bc7 bellard
    uint8_t csp_param;
89 85571bc7 bellard
    uint8_t csp_value;
90 85571bc7 bellard
    uint8_t csp_mode;
91 85571bc7 bellard
    uint8_t csp_regs[256];
92 85571bc7 bellard
    uint8_t csp_index;
93 85571bc7 bellard
    uint8_t csp_reg83[4];
94 85571bc7 bellard
    int csp_reg83r;
95 85571bc7 bellard
    int csp_reg83w;
96 85571bc7 bellard
97 d75d9f6b bellard
    uint8_t in2_data[10];
98 85571bc7 bellard
    uint8_t out_data[50];
99 85571bc7 bellard
    uint8_t test_reg;
100 85571bc7 bellard
    uint8_t last_read_byte;
101 85571bc7 bellard
    int nzero;
102 27503323 bellard
103 27503323 bellard
    int left_till_irq;
104 27503323 bellard
105 85571bc7 bellard
    int dma_running;
106 85571bc7 bellard
    int bytes_per_second;
107 85571bc7 bellard
    int align;
108 1d14ffa9 bellard
    int audio_free;
109 1d14ffa9 bellard
    SWVoiceOut *voice;
110 85571bc7 bellard
111 1d14ffa9 bellard
    QEMUTimer *aux_ts;
112 5e2a6443 bellard
    /* mixer state */
113 5e2a6443 bellard
    int mixer_nreg;
114 202a456a bellard
    uint8_t mixer_regs[256];
115 5e2a6443 bellard
} SB16State;
116 27503323 bellard
117 1d14ffa9 bellard
static void SB_audio_callback (void *opaque, int free);
118 1d14ffa9 bellard
119 85571bc7 bellard
static int magic_of_irq (int irq)
120 85571bc7 bellard
{
121 85571bc7 bellard
    switch (irq) {
122 85571bc7 bellard
    case 5:
123 85571bc7 bellard
        return 2;
124 85571bc7 bellard
    case 7:
125 85571bc7 bellard
        return 4;
126 85571bc7 bellard
    case 9:
127 85571bc7 bellard
        return 1;
128 85571bc7 bellard
    case 10:
129 85571bc7 bellard
        return 8;
130 85571bc7 bellard
    default:
131 85571bc7 bellard
        dolog ("bad irq %d\n", irq);
132 85571bc7 bellard
        return 2;
133 85571bc7 bellard
    }
134 85571bc7 bellard
}
135 85571bc7 bellard
136 85571bc7 bellard
static int irq_of_magic (int magic)
137 85571bc7 bellard
{
138 85571bc7 bellard
    switch (magic) {
139 85571bc7 bellard
    case 1:
140 85571bc7 bellard
        return 9;
141 85571bc7 bellard
    case 2:
142 85571bc7 bellard
        return 5;
143 85571bc7 bellard
    case 4:
144 85571bc7 bellard
        return 7;
145 85571bc7 bellard
    case 8:
146 85571bc7 bellard
        return 10;
147 85571bc7 bellard
    default:
148 85571bc7 bellard
        dolog ("bad irq magic %d\n", magic);
149 85571bc7 bellard
        return -1;
150 85571bc7 bellard
    }
151 85571bc7 bellard
}
152 85571bc7 bellard
153 85571bc7 bellard
#if 0
154 5e2a6443 bellard
static void log_dsp (SB16State *dsp)
155 5e2a6443 bellard
{
156 85571bc7 bellard
    ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
157 85571bc7 bellard
            dsp->fmt_stereo ? "Stereo" : "Mono",
158 85571bc7 bellard
            dsp->fmt_signed ? "Signed" : "Unsigned",
159 85571bc7 bellard
            dsp->fmt_bits,
160 85571bc7 bellard
            dsp->dma_auto ? "Auto" : "Single",
161 85571bc7 bellard
            dsp->block_size,
162 85571bc7 bellard
            dsp->freq,
163 85571bc7 bellard
            dsp->time_const,
164 85571bc7 bellard
            dsp->speaker);
165 85571bc7 bellard
}
166 85571bc7 bellard
#endif
167 85571bc7 bellard
168 85571bc7 bellard
static void speaker (SB16State *s, int on)
169 85571bc7 bellard
{
170 85571bc7 bellard
    s->speaker = on;
171 85571bc7 bellard
    /* AUD_enable (s->voice, on); */
172 27503323 bellard
}
173 27503323 bellard
174 85571bc7 bellard
static void control (SB16State *s, int hold)
175 27503323 bellard
{
176 85571bc7 bellard
    int dma = s->use_hdma ? s->hdma : s->dma;
177 85571bc7 bellard
    s->dma_running = hold;
178 85571bc7 bellard
179 85571bc7 bellard
    ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
180 85571bc7 bellard
181 27503323 bellard
    if (hold) {
182 85571bc7 bellard
        DMA_hold_DREQ (dma);
183 1d14ffa9 bellard
        AUD_set_active_out (s->voice, 1);
184 27503323 bellard
    }
185 27503323 bellard
    else {
186 85571bc7 bellard
        DMA_release_DREQ (dma);
187 1d14ffa9 bellard
        AUD_set_active_out (s->voice, 0);
188 27503323 bellard
    }
189 27503323 bellard
}
190 27503323 bellard
191 85571bc7 bellard
static void aux_timer (void *opaque)
192 27503323 bellard
{
193 85571bc7 bellard
    SB16State *s = opaque;
194 85571bc7 bellard
    s->can_write = 1;
195 d537cf6c pbrook
    qemu_irq_raise (s->pic[s->irq]);
196 85571bc7 bellard
}
197 85571bc7 bellard
198 85571bc7 bellard
#define DMA8_AUTO 1
199 85571bc7 bellard
#define DMA8_HIGH 2
200 85571bc7 bellard
201 feea13e1 bellard
static void continue_dma8 (SB16State *s)
202 feea13e1 bellard
{
203 feea13e1 bellard
    if (s->freq > 0) {
204 feea13e1 bellard
        audsettings_t as;
205 feea13e1 bellard
206 feea13e1 bellard
        s->audio_free = 0;
207 feea13e1 bellard
208 feea13e1 bellard
        as.freq = s->freq;
209 feea13e1 bellard
        as.nchannels = 1 << s->fmt_stereo;
210 feea13e1 bellard
        as.fmt = s->fmt;
211 d929eba5 bellard
        as.endianness = 0;
212 feea13e1 bellard
213 feea13e1 bellard
        s->voice = AUD_open_out (
214 feea13e1 bellard
            &s->card,
215 feea13e1 bellard
            s->voice,
216 feea13e1 bellard
            "sb16",
217 feea13e1 bellard
            s,
218 feea13e1 bellard
            SB_audio_callback,
219 d929eba5 bellard
            &as
220 feea13e1 bellard
            );
221 feea13e1 bellard
    }
222 feea13e1 bellard
223 feea13e1 bellard
    control (s, 1);
224 feea13e1 bellard
}
225 feea13e1 bellard
226 85571bc7 bellard
static void dma_cmd8 (SB16State *s, int mask, int dma_len)
227 85571bc7 bellard
{
228 85571bc7 bellard
    s->fmt = AUD_FMT_U8;
229 85571bc7 bellard
    s->use_hdma = 0;
230 85571bc7 bellard
    s->fmt_bits = 8;
231 85571bc7 bellard
    s->fmt_signed = 0;
232 85571bc7 bellard
    s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
233 85571bc7 bellard
    if (-1 == s->time_const) {
234 feea13e1 bellard
        if (s->freq <= 0)
235 feea13e1 bellard
            s->freq = 11025;
236 85571bc7 bellard
    }
237 85571bc7 bellard
    else {
238 85571bc7 bellard
        int tmp = (256 - s->time_const);
239 85571bc7 bellard
        s->freq = (1000000 + (tmp / 2)) / tmp;
240 85571bc7 bellard
    }
241 85571bc7 bellard
242 1d14ffa9 bellard
    if (dma_len != -1) {
243 15b61470 bellard
        s->block_size = dma_len << s->fmt_stereo;
244 1d14ffa9 bellard
    }
245 15b61470 bellard
    else {
246 15b61470 bellard
        /* This is apparently the only way to make both Act1/PL
247 15b61470 bellard
           and SecondReality/FC work
248 15b61470 bellard

249 15b61470 bellard
           Act1 sets block size via command 0x48 and it's an odd number
250 15b61470 bellard
           SR does the same with even number
251 15b61470 bellard
           Both use stereo, and Creatives own documentation states that
252 15b61470 bellard
           0x48 sets block size in bytes less one.. go figure */
253 15b61470 bellard
        s->block_size &= ~s->fmt_stereo;
254 15b61470 bellard
    }
255 85571bc7 bellard
256 85571bc7 bellard
    s->freq >>= s->fmt_stereo;
257 85571bc7 bellard
    s->left_till_irq = s->block_size;
258 85571bc7 bellard
    s->bytes_per_second = (s->freq << s->fmt_stereo);
259 85571bc7 bellard
    /* s->highspeed = (mask & DMA8_HIGH) != 0; */
260 85571bc7 bellard
    s->dma_auto = (mask & DMA8_AUTO) != 0;
261 85571bc7 bellard
    s->align = (1 << s->fmt_stereo) - 1;
262 85571bc7 bellard
263 1d14ffa9 bellard
    if (s->block_size & s->align) {
264 1d14ffa9 bellard
        dolog ("warning: misaligned block size %d, alignment %d\n",
265 1d14ffa9 bellard
               s->block_size, s->align + 1);
266 1d14ffa9 bellard
    }
267 15b61470 bellard
268 85571bc7 bellard
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
269 85571bc7 bellard
            "dma %d, auto %d, fifo %d, high %d\n",
270 85571bc7 bellard
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
271 85571bc7 bellard
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
272 85571bc7 bellard
273 feea13e1 bellard
    continue_dma8 (s);
274 85571bc7 bellard
    speaker (s, 1);
275 85571bc7 bellard
}
276 27503323 bellard
277 85571bc7 bellard
static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
278 85571bc7 bellard
{
279 85571bc7 bellard
    s->use_hdma = cmd < 0xc0;
280 85571bc7 bellard
    s->fifo = (cmd >> 1) & 1;
281 85571bc7 bellard
    s->dma_auto = (cmd >> 2) & 1;
282 85571bc7 bellard
    s->fmt_signed = (d0 >> 4) & 1;
283 85571bc7 bellard
    s->fmt_stereo = (d0 >> 5) & 1;
284 27503323 bellard
285 27503323 bellard
    switch (cmd >> 4) {
286 27503323 bellard
    case 11:
287 85571bc7 bellard
        s->fmt_bits = 16;
288 27503323 bellard
        break;
289 27503323 bellard
290 27503323 bellard
    case 12:
291 85571bc7 bellard
        s->fmt_bits = 8;
292 27503323 bellard
        break;
293 27503323 bellard
    }
294 27503323 bellard
295 85571bc7 bellard
    if (-1 != s->time_const) {
296 85571bc7 bellard
#if 1
297 85571bc7 bellard
        int tmp = 256 - s->time_const;
298 85571bc7 bellard
        s->freq = (1000000 + (tmp / 2)) / tmp;
299 85571bc7 bellard
#else
300 85571bc7 bellard
        /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
301 85571bc7 bellard
        s->freq = 1000000 / ((255 - s->time_const));
302 85571bc7 bellard
#endif
303 85571bc7 bellard
        s->time_const = -1;
304 27503323 bellard
    }
305 27503323 bellard
306 85571bc7 bellard
    s->block_size = dma_len + 1;
307 85571bc7 bellard
    s->block_size <<= (s->fmt_bits == 16);
308 15b61470 bellard
    if (!s->dma_auto) {
309 15b61470 bellard
        /* It is clear that for DOOM and auto-init this value
310 15b61470 bellard
           shouldn't take stereo into account, while Miles Sound Systems
311 15b61470 bellard
           setsound.exe with single transfer mode wouldn't work without it
312 15b61470 bellard
           wonders of SB16 yet again */
313 85571bc7 bellard
        s->block_size <<= s->fmt_stereo;
314 15b61470 bellard
    }
315 27503323 bellard
316 85571bc7 bellard
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
317 85571bc7 bellard
            "dma %d, auto %d, fifo %d, high %d\n",
318 85571bc7 bellard
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
319 85571bc7 bellard
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
320 27503323 bellard
321 85571bc7 bellard
    if (16 == s->fmt_bits) {
322 85571bc7 bellard
        if (s->fmt_signed) {
323 85571bc7 bellard
            s->fmt = AUD_FMT_S16;
324 27503323 bellard
        }
325 27503323 bellard
        else {
326 85571bc7 bellard
            s->fmt = AUD_FMT_U16;
327 27503323 bellard
        }
328 27503323 bellard
    }
329 27503323 bellard
    else {
330 85571bc7 bellard
        if (s->fmt_signed) {
331 85571bc7 bellard
            s->fmt = AUD_FMT_S8;
332 27503323 bellard
        }
333 27503323 bellard
        else {
334 85571bc7 bellard
            s->fmt = AUD_FMT_U8;
335 27503323 bellard
        }
336 27503323 bellard
    }
337 27503323 bellard
338 85571bc7 bellard
    s->left_till_irq = s->block_size;
339 27503323 bellard
340 85571bc7 bellard
    s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
341 85571bc7 bellard
    s->highspeed = 0;
342 85571bc7 bellard
    s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
343 1d14ffa9 bellard
    if (s->block_size & s->align) {
344 1d14ffa9 bellard
        dolog ("warning: misaligned block size %d, alignment %d\n",
345 1d14ffa9 bellard
               s->block_size, s->align + 1);
346 1d14ffa9 bellard
    }
347 27503323 bellard
348 1d14ffa9 bellard
    if (s->freq) {
349 c0fe3827 bellard
        audsettings_t as;
350 c0fe3827 bellard
351 1d14ffa9 bellard
        s->audio_free = 0;
352 c0fe3827 bellard
353 c0fe3827 bellard
        as.freq = s->freq;
354 c0fe3827 bellard
        as.nchannels = 1 << s->fmt_stereo;
355 c0fe3827 bellard
        as.fmt = s->fmt;
356 d929eba5 bellard
        as.endianness = 0;
357 c0fe3827 bellard
358 1d14ffa9 bellard
        s->voice = AUD_open_out (
359 c0fe3827 bellard
            &s->card,
360 1d14ffa9 bellard
            s->voice,
361 1d14ffa9 bellard
            "sb16",
362 1d14ffa9 bellard
            s,
363 1d14ffa9 bellard
            SB_audio_callback,
364 d929eba5 bellard
            &as
365 1d14ffa9 bellard
            );
366 1d14ffa9 bellard
    }
367 27503323 bellard
368 85571bc7 bellard
    control (s, 1);
369 85571bc7 bellard
    speaker (s, 1);
370 27503323 bellard
}
371 27503323 bellard
372 85571bc7 bellard
static inline void dsp_out_data (SB16State *s, uint8_t val)
373 202a456a bellard
{
374 85571bc7 bellard
    ldebug ("outdata %#x\n", val);
375 c0fe3827 bellard
    if ((size_t) s->out_data_len < sizeof (s->out_data)) {
376 85571bc7 bellard
        s->out_data[s->out_data_len++] = val;
377 1d14ffa9 bellard
    }
378 202a456a bellard
}
379 202a456a bellard
380 85571bc7 bellard
static inline uint8_t dsp_get_data (SB16State *s)
381 d75d9f6b bellard
{
382 1d14ffa9 bellard
    if (s->in_index) {
383 85571bc7 bellard
        return s->in2_data[--s->in_index];
384 1d14ffa9 bellard
    }
385 85571bc7 bellard
    else {
386 85571bc7 bellard
        dolog ("buffer underflow\n");
387 d75d9f6b bellard
        return 0;
388 85571bc7 bellard
    }
389 d75d9f6b bellard
}
390 d75d9f6b bellard
391 85571bc7 bellard
static void command (SB16State *s, uint8_t cmd)
392 27503323 bellard
{
393 85571bc7 bellard
    ldebug ("command %#x\n", cmd);
394 27503323 bellard
395 27503323 bellard
    if (cmd > 0xaf && cmd < 0xd0) {
396 85571bc7 bellard
        if (cmd & 8) {
397 85571bc7 bellard
            dolog ("ADC not yet supported (command %#x)\n", cmd);
398 85571bc7 bellard
        }
399 27503323 bellard
400 27503323 bellard
        switch (cmd >> 4) {
401 27503323 bellard
        case 11:
402 27503323 bellard
        case 12:
403 27503323 bellard
            break;
404 27503323 bellard
        default:
405 85571bc7 bellard
            dolog ("%#x wrong bits\n", cmd);
406 27503323 bellard
        }
407 85571bc7 bellard
        s->needed_bytes = 3;
408 27503323 bellard
    }
409 27503323 bellard
    else {
410 1d14ffa9 bellard
        s->needed_bytes = 0;
411 1d14ffa9 bellard
412 27503323 bellard
        switch (cmd) {
413 d75d9f6b bellard
        case 0x03:
414 85571bc7 bellard
            dsp_out_data (s, 0x10); /* s->csp_param); */
415 85571bc7 bellard
            goto warn;
416 85571bc7 bellard
417 d329a6fb bellard
        case 0x04:
418 85571bc7 bellard
            s->needed_bytes = 1;
419 85571bc7 bellard
            goto warn;
420 d329a6fb bellard
421 d329a6fb bellard
        case 0x05:
422 85571bc7 bellard
            s->needed_bytes = 2;
423 85571bc7 bellard
            goto warn;
424 85571bc7 bellard
425 85571bc7 bellard
        case 0x08:
426 85571bc7 bellard
            /* __asm__ ("int3"); */
427 85571bc7 bellard
            goto warn;
428 d75d9f6b bellard
429 d329a6fb bellard
        case 0x0e:
430 85571bc7 bellard
            s->needed_bytes = 2;
431 85571bc7 bellard
            goto warn;
432 85571bc7 bellard
433 85571bc7 bellard
        case 0x09:
434 85571bc7 bellard
            dsp_out_data (s, 0xf8);
435 85571bc7 bellard
            goto warn;
436 d329a6fb bellard
437 d329a6fb bellard
        case 0x0f:
438 85571bc7 bellard
            s->needed_bytes = 1;
439 85571bc7 bellard
            goto warn;
440 d329a6fb bellard
441 27503323 bellard
        case 0x10:
442 85571bc7 bellard
            s->needed_bytes = 1;
443 85571bc7 bellard
            goto warn;
444 27503323 bellard
445 27503323 bellard
        case 0x14:
446 85571bc7 bellard
            s->needed_bytes = 2;
447 85571bc7 bellard
            s->block_size = 0;
448 27503323 bellard
            break;
449 27503323 bellard
450 15b61470 bellard
        case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
451 feea13e1 bellard
            dma_cmd8 (s, DMA8_AUTO, -1);
452 15b61470 bellard
            break;
453 15b61470 bellard
454 85571bc7 bellard
        case 0x20:              /* Direct ADC, Juice/PL */
455 85571bc7 bellard
            dsp_out_data (s, 0xff);
456 85571bc7 bellard
            goto warn;
457 27503323 bellard
458 27503323 bellard
        case 0x35:
459 1d14ffa9 bellard
            dolog ("0x35 - MIDI command not implemented\n");
460 27503323 bellard
            break;
461 27503323 bellard
462 27503323 bellard
        case 0x40:
463 85571bc7 bellard
            s->freq = -1;
464 85571bc7 bellard
            s->time_const = -1;
465 85571bc7 bellard
            s->needed_bytes = 1;
466 27503323 bellard
            break;
467 27503323 bellard
468 27503323 bellard
        case 0x41:
469 85571bc7 bellard
            s->freq = -1;
470 85571bc7 bellard
            s->time_const = -1;
471 85571bc7 bellard
            s->needed_bytes = 2;
472 27503323 bellard
            break;
473 27503323 bellard
474 85571bc7 bellard
        case 0x42:
475 85571bc7 bellard
            s->freq = -1;
476 85571bc7 bellard
            s->time_const = -1;
477 85571bc7 bellard
            s->needed_bytes = 2;
478 85571bc7 bellard
            goto warn;
479 85571bc7 bellard
480 d75d9f6b bellard
        case 0x45:
481 85571bc7 bellard
            dsp_out_data (s, 0xaa);
482 85571bc7 bellard
            goto warn;
483 85571bc7 bellard
484 27503323 bellard
        case 0x47:                /* Continue Auto-Initialize DMA 16bit */
485 27503323 bellard
            break;
486 27503323 bellard
487 27503323 bellard
        case 0x48:
488 85571bc7 bellard
            s->needed_bytes = 2;
489 27503323 bellard
            break;
490 27503323 bellard
491 1d14ffa9 bellard
        case 0x74:
492 1d14ffa9 bellard
            s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
493 1d14ffa9 bellard
            dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
494 1d14ffa9 bellard
            break;
495 1d14ffa9 bellard
496 1d14ffa9 bellard
        case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
497 1d14ffa9 bellard
            s->needed_bytes = 2;
498 1d14ffa9 bellard
            dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
499 1d14ffa9 bellard
            break;
500 1d14ffa9 bellard
501 1d14ffa9 bellard
        case 0x76:              /* DMA DAC, 2.6-bit ADPCM */
502 1d14ffa9 bellard
            s->needed_bytes = 2;
503 1d14ffa9 bellard
            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
504 1d14ffa9 bellard
            break;
505 1d14ffa9 bellard
506 1d14ffa9 bellard
        case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */
507 1d14ffa9 bellard
            s->needed_bytes = 2;
508 1d14ffa9 bellard
            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
509 1d14ffa9 bellard
            break;
510 1d14ffa9 bellard
511 1d14ffa9 bellard
        case 0x7d:
512 1d14ffa9 bellard
            dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
513 1d14ffa9 bellard
            dolog ("not implemented\n");
514 1d14ffa9 bellard
            break;
515 1d14ffa9 bellard
516 1d14ffa9 bellard
        case 0x7f:
517 1d14ffa9 bellard
            dolog (
518 1d14ffa9 bellard
                "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
519 1d14ffa9 bellard
                );
520 1d14ffa9 bellard
            dolog ("not implemented\n");
521 1d14ffa9 bellard
            break;
522 1d14ffa9 bellard
523 27503323 bellard
        case 0x80:
524 85571bc7 bellard
            s->needed_bytes = 2;
525 27503323 bellard
            break;
526 27503323 bellard
527 27503323 bellard
        case 0x90:
528 27503323 bellard
        case 0x91:
529 85571bc7 bellard
            dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
530 85571bc7 bellard
            break;
531 27503323 bellard
532 85571bc7 bellard
        case 0xd0:              /* halt DMA operation. 8bit */
533 85571bc7 bellard
            control (s, 0);
534 85571bc7 bellard
            break;
535 27503323 bellard
536 85571bc7 bellard
        case 0xd1:              /* speaker on */
537 85571bc7 bellard
            speaker (s, 1);
538 27503323 bellard
            break;
539 27503323 bellard
540 85571bc7 bellard
        case 0xd3:              /* speaker off */
541 85571bc7 bellard
            speaker (s, 0);
542 85571bc7 bellard
            break;
543 27503323 bellard
544 85571bc7 bellard
        case 0xd4:              /* continue DMA operation. 8bit */
545 feea13e1 bellard
            /* KQ6 (or maybe Sierras audblst.drv in general) resets
546 feea13e1 bellard
               the frequency between halt/continue */
547 feea13e1 bellard
            continue_dma8 (s);
548 27503323 bellard
            break;
549 27503323 bellard
550 85571bc7 bellard
        case 0xd5:              /* halt DMA operation. 16bit */
551 85571bc7 bellard
            control (s, 0);
552 27503323 bellard
            break;
553 27503323 bellard
554 85571bc7 bellard
        case 0xd6:              /* continue DMA operation. 16bit */
555 85571bc7 bellard
            control (s, 1);
556 27503323 bellard
            break;
557 27503323 bellard
558 85571bc7 bellard
        case 0xd9:              /* exit auto-init DMA after this block. 16bit */
559 85571bc7 bellard
            s->dma_auto = 0;
560 85571bc7 bellard
            break;
561 27503323 bellard
562 85571bc7 bellard
        case 0xda:              /* exit auto-init DMA after this block. 8bit */
563 85571bc7 bellard
            s->dma_auto = 0;
564 27503323 bellard
            break;
565 27503323 bellard
566 1d14ffa9 bellard
        case 0xe0:              /* DSP identification */
567 85571bc7 bellard
            s->needed_bytes = 1;
568 1d14ffa9 bellard
            break;
569 27503323 bellard
570 27503323 bellard
        case 0xe1:
571 85571bc7 bellard
            dsp_out_data (s, s->ver & 0xff);
572 85571bc7 bellard
            dsp_out_data (s, s->ver >> 8);
573 85571bc7 bellard
            break;
574 85571bc7 bellard
575 85571bc7 bellard
        case 0xe2:
576 85571bc7 bellard
            s->needed_bytes = 1;
577 85571bc7 bellard
            goto warn;
578 27503323 bellard
579 d329a6fb bellard
        case 0xe3:
580 d329a6fb bellard
            {
581 d329a6fb bellard
                int i;
582 85571bc7 bellard
                for (i = sizeof (e3) - 1; i >= 0; --i)
583 85571bc7 bellard
                    dsp_out_data (s, e3[i]);
584 d329a6fb bellard
            }
585 85571bc7 bellard
            break;
586 d329a6fb bellard
587 d75d9f6b bellard
        case 0xe4:              /* write test reg */
588 85571bc7 bellard
            s->needed_bytes = 1;
589 d75d9f6b bellard
            break;
590 d75d9f6b bellard
591 85571bc7 bellard
        case 0xe7:
592 85571bc7 bellard
            dolog ("Attempt to probe for ESS (0xe7)?\n");
593 1d14ffa9 bellard
            break;
594 85571bc7 bellard
595 d75d9f6b bellard
        case 0xe8:              /* read test reg */
596 85571bc7 bellard
            dsp_out_data (s, s->test_reg);
597 d75d9f6b bellard
            break;
598 d75d9f6b bellard
599 27503323 bellard
        case 0xf2:
600 85571bc7 bellard
        case 0xf3:
601 85571bc7 bellard
            dsp_out_data (s, 0xaa);
602 85571bc7 bellard
            s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
603 d537cf6c pbrook
            qemu_irq_raise (s->pic[s->irq]);
604 85571bc7 bellard
            break;
605 27503323 bellard
606 d75d9f6b bellard
        case 0xf9:
607 85571bc7 bellard
            s->needed_bytes = 1;
608 85571bc7 bellard
            goto warn;
609 d75d9f6b bellard
610 d75d9f6b bellard
        case 0xfa:
611 85571bc7 bellard
            dsp_out_data (s, 0);
612 85571bc7 bellard
            goto warn;
613 d75d9f6b bellard
614 d75d9f6b bellard
        case 0xfc:              /* FIXME */
615 85571bc7 bellard
            dsp_out_data (s, 0);
616 85571bc7 bellard
            goto warn;
617 d75d9f6b bellard
618 27503323 bellard
        default:
619 1d14ffa9 bellard
            dolog ("Unrecognized command %#x\n", cmd);
620 1d14ffa9 bellard
            break;
621 27503323 bellard
        }
622 27503323 bellard
    }
623 85571bc7 bellard
624 1d14ffa9 bellard
    if (!s->needed_bytes) {
625 85571bc7 bellard
        ldebug ("\n");
626 1d14ffa9 bellard
    }
627 1d14ffa9 bellard
628 1d14ffa9 bellard
 exit:
629 1d14ffa9 bellard
    if (!s->needed_bytes) {
630 1d14ffa9 bellard
        s->cmd = -1;
631 1d14ffa9 bellard
    }
632 1d14ffa9 bellard
    else {
633 1d14ffa9 bellard
        s->cmd = cmd;
634 1d14ffa9 bellard
    }
635 27503323 bellard
    return;
636 27503323 bellard
637 85571bc7 bellard
 warn:
638 81eea5eb bellard
    dolog ("warning: command %#x,%d is not truly understood yet\n",
639 85571bc7 bellard
           cmd, s->needed_bytes);
640 1d14ffa9 bellard
    goto exit;
641 1d14ffa9 bellard
642 27503323 bellard
}
643 27503323 bellard
644 85571bc7 bellard
static uint16_t dsp_get_lohi (SB16State *s)
645 85571bc7 bellard
{
646 85571bc7 bellard
    uint8_t hi = dsp_get_data (s);
647 85571bc7 bellard
    uint8_t lo = dsp_get_data (s);
648 85571bc7 bellard
    return (hi << 8) | lo;
649 85571bc7 bellard
}
650 85571bc7 bellard
651 85571bc7 bellard
static uint16_t dsp_get_hilo (SB16State *s)
652 85571bc7 bellard
{
653 85571bc7 bellard
    uint8_t lo = dsp_get_data (s);
654 85571bc7 bellard
    uint8_t hi = dsp_get_data (s);
655 85571bc7 bellard
    return (hi << 8) | lo;
656 85571bc7 bellard
}
657 85571bc7 bellard
658 85571bc7 bellard
static void complete (SB16State *s)
659 27503323 bellard
{
660 d75d9f6b bellard
    int d0, d1, d2;
661 85571bc7 bellard
    ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
662 85571bc7 bellard
            s->cmd, s->in_index, s->needed_bytes);
663 27503323 bellard
664 85571bc7 bellard
    if (s->cmd > 0xaf && s->cmd < 0xd0) {
665 85571bc7 bellard
        d2 = dsp_get_data (s);
666 85571bc7 bellard
        d1 = dsp_get_data (s);
667 85571bc7 bellard
        d0 = dsp_get_data (s);
668 27503323 bellard
669 85571bc7 bellard
        if (s->cmd & 8) {
670 85571bc7 bellard
            dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
671 85571bc7 bellard
                   s->cmd, d0, d1, d2);
672 85571bc7 bellard
        }
673 85571bc7 bellard
        else {
674 85571bc7 bellard
            ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
675 85571bc7 bellard
                    s->cmd, d0, d1, d2);
676 85571bc7 bellard
            dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
677 85571bc7 bellard
        }
678 27503323 bellard
    }
679 27503323 bellard
    else {
680 85571bc7 bellard
        switch (s->cmd) {
681 d329a6fb bellard
        case 0x04:
682 85571bc7 bellard
            s->csp_mode = dsp_get_data (s);
683 85571bc7 bellard
            s->csp_reg83r = 0;
684 85571bc7 bellard
            s->csp_reg83w = 0;
685 85571bc7 bellard
            ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
686 d75d9f6b bellard
            break;
687 d75d9f6b bellard
688 85571bc7 bellard
        case 0x05:
689 85571bc7 bellard
            s->csp_param = dsp_get_data (s);
690 85571bc7 bellard
            s->csp_value = dsp_get_data (s);
691 85571bc7 bellard
            ldebug ("CSP command 0x05: param=%#x value=%#x\n",
692 85571bc7 bellard
                    s->csp_param,
693 85571bc7 bellard
                    s->csp_value);
694 d329a6fb bellard
            break;
695 27503323 bellard
696 d75d9f6b bellard
        case 0x0e:
697 85571bc7 bellard
            d0 = dsp_get_data (s);
698 85571bc7 bellard
            d1 = dsp_get_data (s);
699 85571bc7 bellard
            ldebug ("write CSP register %d <- %#x\n", d1, d0);
700 85571bc7 bellard
            if (d1 == 0x83) {
701 85571bc7 bellard
                ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
702 85571bc7 bellard
                s->csp_reg83[s->csp_reg83r % 4] = d0;
703 85571bc7 bellard
                s->csp_reg83r += 1;
704 85571bc7 bellard
            }
705 1d14ffa9 bellard
            else {
706 85571bc7 bellard
                s->csp_regs[d1] = d0;
707 1d14ffa9 bellard
            }
708 27503323 bellard
            break;
709 27503323 bellard
710 85571bc7 bellard
        case 0x0f:
711 85571bc7 bellard
            d0 = dsp_get_data (s);
712 85571bc7 bellard
            ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
713 85571bc7 bellard
                    d0, s->csp_regs[d0], s->csp_mode);
714 85571bc7 bellard
            if (d0 == 0x83) {
715 85571bc7 bellard
                ldebug ("0x83[%d] -> %#x\n",
716 85571bc7 bellard
                        s->csp_reg83w,
717 85571bc7 bellard
                        s->csp_reg83[s->csp_reg83w % 4]);
718 85571bc7 bellard
                dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
719 85571bc7 bellard
                s->csp_reg83w += 1;
720 85571bc7 bellard
            }
721 1d14ffa9 bellard
            else {
722 85571bc7 bellard
                dsp_out_data (s, s->csp_regs[d0]);
723 1d14ffa9 bellard
            }
724 85571bc7 bellard
            break;
725 27503323 bellard
726 85571bc7 bellard
        case 0x10:
727 85571bc7 bellard
            d0 = dsp_get_data (s);
728 85571bc7 bellard
            dolog ("cmd 0x10 d0=%#x\n", d0);
729 85571bc7 bellard
            break;
730 27503323 bellard
731 85571bc7 bellard
        case 0x14:
732 15b61470 bellard
            dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
733 85571bc7 bellard
            break;
734 27503323 bellard
735 27503323 bellard
        case 0x40:
736 85571bc7 bellard
            s->time_const = dsp_get_data (s);
737 85571bc7 bellard
            ldebug ("set time const %d\n", s->time_const);
738 27503323 bellard
            break;
739 27503323 bellard
740 85571bc7 bellard
        case 0x42:              /* FT2 sets output freq with this, go figure */
741 1d14ffa9 bellard
#if 0
742 85571bc7 bellard
            dolog ("cmd 0x42 might not do what it think it should\n");
743 1d14ffa9 bellard
#endif
744 85571bc7 bellard
        case 0x41:
745 85571bc7 bellard
            s->freq = dsp_get_hilo (s);
746 85571bc7 bellard
            ldebug ("set freq %d\n", s->freq);
747 27503323 bellard
            break;
748 27503323 bellard
749 27503323 bellard
        case 0x48:
750 15b61470 bellard
            s->block_size = dsp_get_lohi (s) + 1;
751 85571bc7 bellard
            ldebug ("set dma block len %d\n", s->block_size);
752 85571bc7 bellard
            break;
753 85571bc7 bellard
754 1d14ffa9 bellard
        case 0x74:
755 1d14ffa9 bellard
        case 0x75:
756 1d14ffa9 bellard
        case 0x76:
757 1d14ffa9 bellard
        case 0x77:
758 1d14ffa9 bellard
            /* ADPCM stuff, ignore */
759 1d14ffa9 bellard
            break;
760 1d14ffa9 bellard
761 85571bc7 bellard
        case 0x80:
762 85571bc7 bellard
            {
763 15b61470 bellard
                int freq, samples, bytes;
764 85571bc7 bellard
                int64_t ticks;
765 85571bc7 bellard
766 15b61470 bellard
                freq = s->freq > 0 ? s->freq : 11025;
767 15b61470 bellard
                samples = dsp_get_lohi (s) + 1;
768 85571bc7 bellard
                bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
769 15b61470 bellard
                ticks = (bytes * ticks_per_sec) / freq;
770 1d14ffa9 bellard
                if (ticks < ticks_per_sec / 1024) {
771 d537cf6c pbrook
                    qemu_irq_raise (s->pic[s->irq]);
772 1d14ffa9 bellard
                }
773 1d14ffa9 bellard
                else {
774 1d14ffa9 bellard
                    if (s->aux_ts) {
775 1d14ffa9 bellard
                        qemu_mod_timer (
776 1d14ffa9 bellard
                            s->aux_ts,
777 1d14ffa9 bellard
                            qemu_get_clock (vm_clock) + ticks
778 1d14ffa9 bellard
                            );
779 1d14ffa9 bellard
                    }
780 1d14ffa9 bellard
                }
781 26a76461 bellard
                ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
782 85571bc7 bellard
            }
783 27503323 bellard
            break;
784 27503323 bellard
785 27503323 bellard
        case 0xe0:
786 85571bc7 bellard
            d0 = dsp_get_data (s);
787 85571bc7 bellard
            s->out_data_len = 0;
788 85571bc7 bellard
            ldebug ("E0 data = %#x\n", d0);
789 1d14ffa9 bellard
            dsp_out_data (s, ~d0);
790 d75d9f6b bellard
            break;
791 d75d9f6b bellard
792 85571bc7 bellard
        case 0xe2:
793 85571bc7 bellard
            d0 = dsp_get_data (s);
794 15b61470 bellard
            ldebug ("E2 = %#x\n", d0);
795 d75d9f6b bellard
            break;
796 d75d9f6b bellard
797 85571bc7 bellard
        case 0xe4:
798 85571bc7 bellard
            s->test_reg = dsp_get_data (s);
799 85571bc7 bellard
            break;
800 d75d9f6b bellard
801 d75d9f6b bellard
        case 0xf9:
802 85571bc7 bellard
            d0 = dsp_get_data (s);
803 85571bc7 bellard
            ldebug ("command 0xf9 with %#x\n", d0);
804 d75d9f6b bellard
            switch (d0) {
805 85571bc7 bellard
            case 0x0e:
806 85571bc7 bellard
                dsp_out_data (s, 0xff);
807 85571bc7 bellard
                break;
808 85571bc7 bellard
809 85571bc7 bellard
            case 0x0f:
810 85571bc7 bellard
                dsp_out_data (s, 0x07);
811 85571bc7 bellard
                break;
812 85571bc7 bellard
813 d75d9f6b bellard
            case 0x37:
814 85571bc7 bellard
                dsp_out_data (s, 0x38);
815 85571bc7 bellard
                break;
816 85571bc7 bellard
817 d75d9f6b bellard
            default:
818 85571bc7 bellard
                dsp_out_data (s, 0x00);
819 85571bc7 bellard
                break;
820 d75d9f6b bellard
            }
821 27503323 bellard
            break;
822 27503323 bellard
823 27503323 bellard
        default:
824 85571bc7 bellard
            dolog ("complete: unrecognized command %#x\n", s->cmd);
825 5e2a6443 bellard
            return;
826 27503323 bellard
        }
827 27503323 bellard
    }
828 27503323 bellard
829 85571bc7 bellard
    ldebug ("\n");
830 85571bc7 bellard
    s->cmd = -1;
831 27503323 bellard
    return;
832 27503323 bellard
}
833 27503323 bellard
834 feea13e1 bellard
static void legacy_reset (SB16State *s)
835 feea13e1 bellard
{
836 feea13e1 bellard
    audsettings_t as;
837 feea13e1 bellard
838 feea13e1 bellard
    s->freq = 11025;
839 feea13e1 bellard
    s->fmt_signed = 0;
840 feea13e1 bellard
    s->fmt_bits = 8;
841 feea13e1 bellard
    s->fmt_stereo = 0;
842 feea13e1 bellard
843 feea13e1 bellard
    as.freq = s->freq;
844 feea13e1 bellard
    as.nchannels = 1;
845 feea13e1 bellard
    as.fmt = AUD_FMT_U8;
846 d929eba5 bellard
    as.endianness = 0;
847 feea13e1 bellard
848 feea13e1 bellard
    s->voice = AUD_open_out (
849 feea13e1 bellard
        &s->card,
850 feea13e1 bellard
        s->voice,
851 feea13e1 bellard
        "sb16",
852 feea13e1 bellard
        s,
853 feea13e1 bellard
        SB_audio_callback,
854 d929eba5 bellard
        &as
855 feea13e1 bellard
        );
856 feea13e1 bellard
857 feea13e1 bellard
    /* Not sure about that... */
858 feea13e1 bellard
    /* AUD_set_active_out (s->voice, 1); */
859 feea13e1 bellard
}
860 feea13e1 bellard
861 85571bc7 bellard
static void reset (SB16State *s)
862 85571bc7 bellard
{
863 d537cf6c pbrook
    qemu_irq_lower (s->pic[s->irq]);
864 85571bc7 bellard
    if (s->dma_auto) {
865 d537cf6c pbrook
        qemu_irq_raise (s->pic[s->irq]);
866 d537cf6c pbrook
        qemu_irq_lower (s->pic[s->irq]);
867 85571bc7 bellard
    }
868 85571bc7 bellard
869 85571bc7 bellard
    s->mixer_regs[0x82] = 0;
870 85571bc7 bellard
    s->dma_auto = 0;
871 85571bc7 bellard
    s->in_index = 0;
872 85571bc7 bellard
    s->out_data_len = 0;
873 85571bc7 bellard
    s->left_till_irq = 0;
874 85571bc7 bellard
    s->needed_bytes = 0;
875 85571bc7 bellard
    s->block_size = -1;
876 85571bc7 bellard
    s->nzero = 0;
877 85571bc7 bellard
    s->highspeed = 0;
878 85571bc7 bellard
    s->v2x6 = 0;
879 1d14ffa9 bellard
    s->cmd = -1;
880 85571bc7 bellard
881 85571bc7 bellard
    dsp_out_data(s, 0xaa);
882 85571bc7 bellard
    speaker (s, 0);
883 85571bc7 bellard
    control (s, 0);
884 feea13e1 bellard
    legacy_reset (s);
885 85571bc7 bellard
}
886 85571bc7 bellard
887 27503323 bellard
static IO_WRITE_PROTO (dsp_write)
888 27503323 bellard
{
889 85571bc7 bellard
    SB16State *s = opaque;
890 27503323 bellard
    int iport;
891 27503323 bellard
892 85571bc7 bellard
    iport = nport - s->port;
893 27503323 bellard
894 85571bc7 bellard
    ldebug ("write %#x <- %#x\n", nport, val);
895 27503323 bellard
    switch (iport) {
896 85571bc7 bellard
    case 0x06:
897 85571bc7 bellard
        switch (val) {
898 85571bc7 bellard
        case 0x00:
899 85571bc7 bellard
            if (s->v2x6 == 1) {
900 85571bc7 bellard
                if (0 && s->highspeed) {
901 85571bc7 bellard
                    s->highspeed = 0;
902 d537cf6c pbrook
                    qemu_irq_lower (s->pic[s->irq]);
903 85571bc7 bellard
                    control (s, 0);
904 85571bc7 bellard
                }
905 1d14ffa9 bellard
                else {
906 85571bc7 bellard
                    reset (s);
907 1d14ffa9 bellard
                }
908 85571bc7 bellard
            }
909 85571bc7 bellard
            s->v2x6 = 0;
910 85571bc7 bellard
            break;
911 85571bc7 bellard
912 85571bc7 bellard
        case 0x01:
913 85571bc7 bellard
        case 0x03:              /* FreeBSD kludge */
914 85571bc7 bellard
            s->v2x6 = 1;
915 85571bc7 bellard
            break;
916 85571bc7 bellard
917 85571bc7 bellard
        case 0xc6:
918 85571bc7 bellard
            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
919 85571bc7 bellard
            break;
920 85571bc7 bellard
921 85571bc7 bellard
        case 0xb8:              /* Panic */
922 85571bc7 bellard
            reset (s);
923 85571bc7 bellard
            break;
924 85571bc7 bellard
925 85571bc7 bellard
        case 0x39:
926 85571bc7 bellard
            dsp_out_data (s, 0x38);
927 85571bc7 bellard
            reset (s);
928 85571bc7 bellard
            s->v2x6 = 0x39;
929 85571bc7 bellard
            break;
930 85571bc7 bellard
931 85571bc7 bellard
        default:
932 85571bc7 bellard
            s->v2x6 = val;
933 85571bc7 bellard
            break;
934 27503323 bellard
        }
935 27503323 bellard
        break;
936 27503323 bellard
937 85571bc7 bellard
    case 0x0c:                  /* write data or command | write status */
938 85571bc7 bellard
/*         if (s->highspeed) */
939 85571bc7 bellard
/*             break; */
940 85571bc7 bellard
941 85571bc7 bellard
        if (0 == s->needed_bytes) {
942 85571bc7 bellard
            command (s, val);
943 85571bc7 bellard
#if 0
944 85571bc7 bellard
            if (0 == s->needed_bytes) {
945 85571bc7 bellard
                log_dsp (s);
946 27503323 bellard
            }
947 85571bc7 bellard
#endif
948 27503323 bellard
        }
949 27503323 bellard
        else {
950 85571bc7 bellard
            if (s->in_index == sizeof (s->in2_data)) {
951 d75d9f6b bellard
                dolog ("in data overrun\n");
952 d75d9f6b bellard
            }
953 d75d9f6b bellard
            else {
954 85571bc7 bellard
                s->in2_data[s->in_index++] = val;
955 85571bc7 bellard
                if (s->in_index == s->needed_bytes) {
956 85571bc7 bellard
                    s->needed_bytes = 0;
957 85571bc7 bellard
                    complete (s);
958 85571bc7 bellard
#if 0
959 85571bc7 bellard
                    log_dsp (s);
960 85571bc7 bellard
#endif
961 85571bc7 bellard
                }
962 27503323 bellard
            }
963 27503323 bellard
        }
964 27503323 bellard
        break;
965 27503323 bellard
966 27503323 bellard
    default:
967 85571bc7 bellard
        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
968 5e2a6443 bellard
        break;
969 27503323 bellard
    }
970 27503323 bellard
}
971 27503323 bellard
972 27503323 bellard
static IO_READ_PROTO (dsp_read)
973 27503323 bellard
{
974 85571bc7 bellard
    SB16State *s = opaque;
975 85571bc7 bellard
    int iport, retval, ack = 0;
976 27503323 bellard
977 85571bc7 bellard
    iport = nport - s->port;
978 27503323 bellard
979 27503323 bellard
    switch (iport) {
980 85571bc7 bellard
    case 0x06:                  /* reset */
981 85571bc7 bellard
        retval = 0xff;
982 d75d9f6b bellard
        break;
983 27503323 bellard
984 85571bc7 bellard
    case 0x0a:                  /* read data */
985 85571bc7 bellard
        if (s->out_data_len) {
986 85571bc7 bellard
            retval = s->out_data[--s->out_data_len];
987 85571bc7 bellard
            s->last_read_byte = retval;
988 85571bc7 bellard
        }
989 85571bc7 bellard
        else {
990 1d14ffa9 bellard
            if (s->cmd != -1) {
991 1d14ffa9 bellard
                dolog ("empty output buffer for command %#x\n",
992 1d14ffa9 bellard
                       s->cmd);
993 1d14ffa9 bellard
            }
994 85571bc7 bellard
            retval = s->last_read_byte;
995 d75d9f6b bellard
            /* goto error; */
996 27503323 bellard
        }
997 27503323 bellard
        break;
998 27503323 bellard
999 85571bc7 bellard
    case 0x0c:                  /* 0 can write */
1000 85571bc7 bellard
        retval = s->can_write ? 0 : 0x80;
1001 27503323 bellard
        break;
1002 27503323 bellard
1003 85571bc7 bellard
    case 0x0d:                  /* timer interrupt clear */
1004 85571bc7 bellard
        /* dolog ("timer interrupt clear\n"); */
1005 85571bc7 bellard
        retval = 0;
1006 85571bc7 bellard
        break;
1007 27503323 bellard
1008 85571bc7 bellard
    case 0x0e:                  /* data available status | irq 8 ack */
1009 85571bc7 bellard
        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1010 85571bc7 bellard
        if (s->mixer_regs[0x82] & 1) {
1011 85571bc7 bellard
            ack = 1;
1012 85571bc7 bellard
            s->mixer_regs[0x82] &= 1;
1013 d537cf6c pbrook
            qemu_irq_lower (s->pic[s->irq]);
1014 85571bc7 bellard
        }
1015 27503323 bellard
        break;
1016 27503323 bellard
1017 85571bc7 bellard
    case 0x0f:                  /* irq 16 ack */
1018 bc0b1dc1 bellard
        retval = 0xff;
1019 85571bc7 bellard
        if (s->mixer_regs[0x82] & 2) {
1020 85571bc7 bellard
            ack = 1;
1021 85571bc7 bellard
            s->mixer_regs[0x82] &= 2;
1022 d537cf6c pbrook
            qemu_irq_lower (s->pic[s->irq]);
1023 85571bc7 bellard
        }
1024 27503323 bellard
        break;
1025 27503323 bellard
1026 27503323 bellard
    default:
1027 27503323 bellard
        goto error;
1028 27503323 bellard
    }
1029 27503323 bellard
1030 1d14ffa9 bellard
    if (!ack) {
1031 85571bc7 bellard
        ldebug ("read %#x -> %#x\n", nport, retval);
1032 1d14ffa9 bellard
    }
1033 27503323 bellard
1034 27503323 bellard
    return retval;
1035 27503323 bellard
1036 27503323 bellard
 error:
1037 1d14ffa9 bellard
    dolog ("warning: dsp_read %#x error\n", nport);
1038 d75d9f6b bellard
    return 0xff;
1039 27503323 bellard
}
1040 27503323 bellard
1041 85571bc7 bellard
static void reset_mixer (SB16State *s)
1042 85571bc7 bellard
{
1043 85571bc7 bellard
    int i;
1044 85571bc7 bellard
1045 85571bc7 bellard
    memset (s->mixer_regs, 0xff, 0x7f);
1046 85571bc7 bellard
    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1047 85571bc7 bellard
1048 85571bc7 bellard
    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
1049 85571bc7 bellard
    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
1050 85571bc7 bellard
    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
1051 85571bc7 bellard
    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
1052 85571bc7 bellard
1053 85571bc7 bellard
    /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1054 85571bc7 bellard
    s->mixer_regs[0x0c] = 0;
1055 85571bc7 bellard
1056 85571bc7 bellard
    /* d5=output filt, d1=stereo switch */
1057 85571bc7 bellard
    s->mixer_regs[0x0e] = 0;
1058 85571bc7 bellard
1059 85571bc7 bellard
    /* voice volume L d5,d7, R d1,d3 */
1060 85571bc7 bellard
    s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1061 85571bc7 bellard
    /* master ... */
1062 85571bc7 bellard
    s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1063 85571bc7 bellard
    /* MIDI ... */
1064 85571bc7 bellard
    s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1065 85571bc7 bellard
1066 85571bc7 bellard
    for (i = 0x30; i < 0x48; i++) {
1067 85571bc7 bellard
        s->mixer_regs[i] = 0x20;
1068 85571bc7 bellard
    }
1069 85571bc7 bellard
}
1070 85571bc7 bellard
1071 27503323 bellard
static IO_WRITE_PROTO(mixer_write_indexb)
1072 27503323 bellard
{
1073 85571bc7 bellard
    SB16State *s = opaque;
1074 c0fe3827 bellard
    (void) nport;
1075 85571bc7 bellard
    s->mixer_nreg = val;
1076 27503323 bellard
}
1077 27503323 bellard
1078 27503323 bellard
static IO_WRITE_PROTO(mixer_write_datab)
1079 27503323 bellard
{
1080 85571bc7 bellard
    SB16State *s = opaque;
1081 85571bc7 bellard
1082 c0fe3827 bellard
    (void) nport;
1083 85571bc7 bellard
    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1084 202a456a bellard
1085 85571bc7 bellard
    switch (s->mixer_nreg) {
1086 d75d9f6b bellard
    case 0x00:
1087 85571bc7 bellard
        reset_mixer (s);
1088 d75d9f6b bellard
        break;
1089 d75d9f6b bellard
1090 d75d9f6b bellard
    case 0x80:
1091 85571bc7 bellard
        {
1092 85571bc7 bellard
            int irq = irq_of_magic (val);
1093 85571bc7 bellard
            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1094 1d14ffa9 bellard
            if (irq > 0) {
1095 85571bc7 bellard
                s->irq = irq;
1096 1d14ffa9 bellard
            }
1097 85571bc7 bellard
        }
1098 d75d9f6b bellard
        break;
1099 27503323 bellard
1100 85571bc7 bellard
    case 0x81:
1101 85571bc7 bellard
        {
1102 85571bc7 bellard
            int dma, hdma;
1103 d75d9f6b bellard
1104 85571bc7 bellard
            dma = lsbindex (val & 0xf);
1105 85571bc7 bellard
            hdma = lsbindex (val & 0xf0);
1106 1d14ffa9 bellard
            if (dma != s->dma || hdma != s->hdma) {
1107 1d14ffa9 bellard
                dolog (
1108 1d14ffa9 bellard
                    "attempt to change DMA "
1109 1d14ffa9 bellard
                    "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1110 1d14ffa9 bellard
                    dma, s->dma, hdma, s->hdma, val);
1111 1d14ffa9 bellard
            }
1112 85571bc7 bellard
#if 0
1113 85571bc7 bellard
            s->dma = dma;
1114 85571bc7 bellard
            s->hdma = hdma;
1115 85571bc7 bellard
#endif
1116 85571bc7 bellard
        }
1117 85571bc7 bellard
        break;
1118 d75d9f6b bellard
1119 85571bc7 bellard
    case 0x82:
1120 85571bc7 bellard
        dolog ("attempt to write into IRQ status register (val=%#x)\n",
1121 85571bc7 bellard
               val);
1122 85571bc7 bellard
        return;
1123 d75d9f6b bellard
1124 85571bc7 bellard
    default:
1125 1d14ffa9 bellard
        if (s->mixer_nreg >= 0x80) {
1126 1d14ffa9 bellard
            ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1127 1d14ffa9 bellard
        }
1128 85571bc7 bellard
        break;
1129 85571bc7 bellard
    }
1130 85571bc7 bellard
1131 85571bc7 bellard
    s->mixer_regs[s->mixer_nreg] = val;
1132 d75d9f6b bellard
}
1133 d75d9f6b bellard
1134 27503323 bellard
static IO_WRITE_PROTO(mixer_write_indexw)
1135 27503323 bellard
{
1136 7d977de7 bellard
    mixer_write_indexb (opaque, nport, val & 0xff);
1137 7d977de7 bellard
    mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1138 27503323 bellard
}
1139 27503323 bellard
1140 27503323 bellard
static IO_READ_PROTO(mixer_read)
1141 27503323 bellard
{
1142 85571bc7 bellard
    SB16State *s = opaque;
1143 c0fe3827 bellard
1144 c0fe3827 bellard
    (void) nport;
1145 15b61470 bellard
#ifndef DEBUG_SB16_MOST
1146 1d14ffa9 bellard
    if (s->mixer_nreg != 0x82) {
1147 1d14ffa9 bellard
        ldebug ("mixer_read[%#x] -> %#x\n",
1148 1d14ffa9 bellard
                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1149 1d14ffa9 bellard
    }
1150 1d14ffa9 bellard
#else
1151 85571bc7 bellard
    ldebug ("mixer_read[%#x] -> %#x\n",
1152 85571bc7 bellard
            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1153 1d14ffa9 bellard
#endif
1154 85571bc7 bellard
    return s->mixer_regs[s->mixer_nreg];
1155 27503323 bellard
}
1156 27503323 bellard
1157 85571bc7 bellard
static int write_audio (SB16State *s, int nchan, int dma_pos,
1158 85571bc7 bellard
                        int dma_len, int len)
1159 27503323 bellard
{
1160 27503323 bellard
    int temp, net;
1161 f9e92e97 bellard
    uint8_t tmpbuf[4096];
1162 27503323 bellard
1163 85571bc7 bellard
    temp = len;
1164 27503323 bellard
    net = 0;
1165 27503323 bellard
1166 27503323 bellard
    while (temp) {
1167 85571bc7 bellard
        int left = dma_len - dma_pos;
1168 c0fe3827 bellard
        int copied;
1169 c0fe3827 bellard
        size_t to_copy;
1170 27503323 bellard
1171 85571bc7 bellard
        to_copy = audio_MIN (temp, left);
1172 c0fe3827 bellard
        if (to_copy > sizeof (tmpbuf)) {
1173 c0fe3827 bellard
            to_copy = sizeof (tmpbuf);
1174 1d14ffa9 bellard
        }
1175 27503323 bellard
1176 85571bc7 bellard
        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1177 85571bc7 bellard
        copied = AUD_write (s->voice, tmpbuf, copied);
1178 27503323 bellard
1179 85571bc7 bellard
        temp -= copied;
1180 85571bc7 bellard
        dma_pos = (dma_pos + copied) % dma_len;
1181 27503323 bellard
        net += copied;
1182 27503323 bellard
1183 1d14ffa9 bellard
        if (!copied) {
1184 85571bc7 bellard
            break;
1185 1d14ffa9 bellard
        }
1186 27503323 bellard
    }
1187 27503323 bellard
1188 27503323 bellard
    return net;
1189 27503323 bellard
}
1190 27503323 bellard
1191 85571bc7 bellard
static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1192 27503323 bellard
{
1193 85571bc7 bellard
    SB16State *s = opaque;
1194 1d14ffa9 bellard
    int till, copy, written, free;
1195 27503323 bellard
1196 85571bc7 bellard
    if (s->left_till_irq < 0) {
1197 85571bc7 bellard
        s->left_till_irq = s->block_size;
1198 27503323 bellard
    }
1199 27503323 bellard
1200 1d14ffa9 bellard
    if (s->voice) {
1201 1d14ffa9 bellard
        free = s->audio_free & ~s->align;
1202 1d14ffa9 bellard
        if ((free <= 0) || !dma_len) {
1203 1d14ffa9 bellard
            return dma_pos;
1204 1d14ffa9 bellard
        }
1205 1d14ffa9 bellard
    }
1206 1d14ffa9 bellard
    else {
1207 1d14ffa9 bellard
        free = dma_len;
1208 27503323 bellard
    }
1209 27503323 bellard
1210 85571bc7 bellard
    copy = free;
1211 85571bc7 bellard
    till = s->left_till_irq;
1212 27503323 bellard
1213 d75d9f6b bellard
#ifdef DEBUG_SB16_MOST
1214 1d14ffa9 bellard
    dolog ("pos:%06d %d till:%d len:%d\n",
1215 1d14ffa9 bellard
           dma_pos, free, till, dma_len);
1216 d75d9f6b bellard
#endif
1217 d75d9f6b bellard
1218 27503323 bellard
    if (till <= copy) {
1219 85571bc7 bellard
        if (0 == s->dma_auto) {
1220 27503323 bellard
            copy = till;
1221 27503323 bellard
        }
1222 27503323 bellard
    }
1223 27503323 bellard
1224 85571bc7 bellard
    written = write_audio (s, nchan, dma_pos, dma_len, copy);
1225 85571bc7 bellard
    dma_pos = (dma_pos + written) % dma_len;
1226 85571bc7 bellard
    s->left_till_irq -= written;
1227 27503323 bellard
1228 85571bc7 bellard
    if (s->left_till_irq <= 0) {
1229 85571bc7 bellard
        s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1230 d537cf6c pbrook
        qemu_irq_raise (s->pic[s->irq]);
1231 85571bc7 bellard
        if (0 == s->dma_auto) {
1232 85571bc7 bellard
            control (s, 0);
1233 85571bc7 bellard
            speaker (s, 0);
1234 27503323 bellard
        }
1235 27503323 bellard
    }
1236 27503323 bellard
1237 d75d9f6b bellard
#ifdef DEBUG_SB16_MOST
1238 15b61470 bellard
    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1239 15b61470 bellard
            dma_pos, free, dma_len, s->left_till_irq, copy, written,
1240 15b61470 bellard
            s->block_size);
1241 d75d9f6b bellard
#endif
1242 27503323 bellard
1243 85571bc7 bellard
    while (s->left_till_irq <= 0) {
1244 85571bc7 bellard
        s->left_till_irq = s->block_size + s->left_till_irq;
1245 27503323 bellard
    }
1246 27503323 bellard
1247 85571bc7 bellard
    return dma_pos;
1248 27503323 bellard
}
1249 27503323 bellard
1250 1d14ffa9 bellard
static void SB_audio_callback (void *opaque, int free)
1251 27503323 bellard
{
1252 85571bc7 bellard
    SB16State *s = opaque;
1253 1d14ffa9 bellard
    s->audio_free = free;
1254 27503323 bellard
}
1255 27503323 bellard
1256 85571bc7 bellard
static void SB_save (QEMUFile *f, void *opaque)
1257 d75d9f6b bellard
{
1258 85571bc7 bellard
    SB16State *s = opaque;
1259 85571bc7 bellard
1260 85571bc7 bellard
    qemu_put_be32s (f, &s->irq);
1261 85571bc7 bellard
    qemu_put_be32s (f, &s->dma);
1262 85571bc7 bellard
    qemu_put_be32s (f, &s->hdma);
1263 85571bc7 bellard
    qemu_put_be32s (f, &s->port);
1264 85571bc7 bellard
    qemu_put_be32s (f, &s->ver);
1265 85571bc7 bellard
    qemu_put_be32s (f, &s->in_index);
1266 85571bc7 bellard
    qemu_put_be32s (f, &s->out_data_len);
1267 85571bc7 bellard
    qemu_put_be32s (f, &s->fmt_stereo);
1268 85571bc7 bellard
    qemu_put_be32s (f, &s->fmt_signed);
1269 85571bc7 bellard
    qemu_put_be32s (f, &s->fmt_bits);
1270 85571bc7 bellard
    qemu_put_be32s (f, &s->fmt);
1271 85571bc7 bellard
    qemu_put_be32s (f, &s->dma_auto);
1272 85571bc7 bellard
    qemu_put_be32s (f, &s->block_size);
1273 85571bc7 bellard
    qemu_put_be32s (f, &s->fifo);
1274 85571bc7 bellard
    qemu_put_be32s (f, &s->freq);
1275 85571bc7 bellard
    qemu_put_be32s (f, &s->time_const);
1276 85571bc7 bellard
    qemu_put_be32s (f, &s->speaker);
1277 85571bc7 bellard
    qemu_put_be32s (f, &s->needed_bytes);
1278 85571bc7 bellard
    qemu_put_be32s (f, &s->cmd);
1279 85571bc7 bellard
    qemu_put_be32s (f, &s->use_hdma);
1280 85571bc7 bellard
    qemu_put_be32s (f, &s->highspeed);
1281 85571bc7 bellard
    qemu_put_be32s (f, &s->can_write);
1282 85571bc7 bellard
    qemu_put_be32s (f, &s->v2x6);
1283 85571bc7 bellard
1284 85571bc7 bellard
    qemu_put_8s (f, &s->csp_param);
1285 85571bc7 bellard
    qemu_put_8s (f, &s->csp_value);
1286 85571bc7 bellard
    qemu_put_8s (f, &s->csp_mode);
1287 85571bc7 bellard
    qemu_put_8s (f, &s->csp_param);
1288 85571bc7 bellard
    qemu_put_buffer (f, s->csp_regs, 256);
1289 85571bc7 bellard
    qemu_put_8s (f, &s->csp_index);
1290 85571bc7 bellard
    qemu_put_buffer (f, s->csp_reg83, 4);
1291 85571bc7 bellard
    qemu_put_be32s (f, &s->csp_reg83r);
1292 85571bc7 bellard
    qemu_put_be32s (f, &s->csp_reg83w);
1293 85571bc7 bellard
1294 85571bc7 bellard
    qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1295 85571bc7 bellard
    qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1296 85571bc7 bellard
    qemu_put_8s (f, &s->test_reg);
1297 85571bc7 bellard
    qemu_put_8s (f, &s->last_read_byte);
1298 85571bc7 bellard
1299 85571bc7 bellard
    qemu_put_be32s (f, &s->nzero);
1300 85571bc7 bellard
    qemu_put_be32s (f, &s->left_till_irq);
1301 85571bc7 bellard
    qemu_put_be32s (f, &s->dma_running);
1302 85571bc7 bellard
    qemu_put_be32s (f, &s->bytes_per_second);
1303 85571bc7 bellard
    qemu_put_be32s (f, &s->align);
1304 85571bc7 bellard
1305 85571bc7 bellard
    qemu_put_be32s (f, &s->mixer_nreg);
1306 85571bc7 bellard
    qemu_put_buffer (f, s->mixer_regs, 256);
1307 d75d9f6b bellard
}
1308 d75d9f6b bellard
1309 85571bc7 bellard
static int SB_load (QEMUFile *f, void *opaque, int version_id)
1310 d75d9f6b bellard
{
1311 85571bc7 bellard
    SB16State *s = opaque;
1312 85571bc7 bellard
1313 1d14ffa9 bellard
    if (version_id != 1) {
1314 85571bc7 bellard
        return -EINVAL;
1315 1d14ffa9 bellard
    }
1316 85571bc7 bellard
1317 85571bc7 bellard
    qemu_get_be32s (f, &s->irq);
1318 85571bc7 bellard
    qemu_get_be32s (f, &s->dma);
1319 85571bc7 bellard
    qemu_get_be32s (f, &s->hdma);
1320 85571bc7 bellard
    qemu_get_be32s (f, &s->port);
1321 85571bc7 bellard
    qemu_get_be32s (f, &s->ver);
1322 85571bc7 bellard
    qemu_get_be32s (f, &s->in_index);
1323 85571bc7 bellard
    qemu_get_be32s (f, &s->out_data_len);
1324 85571bc7 bellard
    qemu_get_be32s (f, &s->fmt_stereo);
1325 85571bc7 bellard
    qemu_get_be32s (f, &s->fmt_signed);
1326 85571bc7 bellard
    qemu_get_be32s (f, &s->fmt_bits);
1327 85571bc7 bellard
    qemu_get_be32s (f, &s->fmt);
1328 85571bc7 bellard
    qemu_get_be32s (f, &s->dma_auto);
1329 85571bc7 bellard
    qemu_get_be32s (f, &s->block_size);
1330 85571bc7 bellard
    qemu_get_be32s (f, &s->fifo);
1331 85571bc7 bellard
    qemu_get_be32s (f, &s->freq);
1332 85571bc7 bellard
    qemu_get_be32s (f, &s->time_const);
1333 85571bc7 bellard
    qemu_get_be32s (f, &s->speaker);
1334 85571bc7 bellard
    qemu_get_be32s (f, &s->needed_bytes);
1335 85571bc7 bellard
    qemu_get_be32s (f, &s->cmd);
1336 85571bc7 bellard
    qemu_get_be32s (f, &s->use_hdma);
1337 85571bc7 bellard
    qemu_get_be32s (f, &s->highspeed);
1338 85571bc7 bellard
    qemu_get_be32s (f, &s->can_write);
1339 85571bc7 bellard
    qemu_get_be32s (f, &s->v2x6);
1340 85571bc7 bellard
1341 85571bc7 bellard
    qemu_get_8s (f, &s->csp_param);
1342 85571bc7 bellard
    qemu_get_8s (f, &s->csp_value);
1343 85571bc7 bellard
    qemu_get_8s (f, &s->csp_mode);
1344 85571bc7 bellard
    qemu_get_8s (f, &s->csp_param);
1345 85571bc7 bellard
    qemu_get_buffer (f, s->csp_regs, 256);
1346 85571bc7 bellard
    qemu_get_8s (f, &s->csp_index);
1347 85571bc7 bellard
    qemu_get_buffer (f, s->csp_reg83, 4);
1348 85571bc7 bellard
    qemu_get_be32s (f, &s->csp_reg83r);
1349 85571bc7 bellard
    qemu_get_be32s (f, &s->csp_reg83w);
1350 85571bc7 bellard
1351 85571bc7 bellard
    qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1352 85571bc7 bellard
    qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1353 85571bc7 bellard
    qemu_get_8s (f, &s->test_reg);
1354 85571bc7 bellard
    qemu_get_8s (f, &s->last_read_byte);
1355 85571bc7 bellard
1356 85571bc7 bellard
    qemu_get_be32s (f, &s->nzero);
1357 85571bc7 bellard
    qemu_get_be32s (f, &s->left_till_irq);
1358 85571bc7 bellard
    qemu_get_be32s (f, &s->dma_running);
1359 85571bc7 bellard
    qemu_get_be32s (f, &s->bytes_per_second);
1360 85571bc7 bellard
    qemu_get_be32s (f, &s->align);
1361 85571bc7 bellard
1362 85571bc7 bellard
    qemu_get_be32s (f, &s->mixer_nreg);
1363 85571bc7 bellard
    qemu_get_buffer (f, s->mixer_regs, 256);
1364 85571bc7 bellard
1365 fb065187 bellard
    if (s->voice) {
1366 c0fe3827 bellard
        AUD_close_out (&s->card, s->voice);
1367 fb065187 bellard
        s->voice = NULL;
1368 fb065187 bellard
    }
1369 85571bc7 bellard
1370 85571bc7 bellard
    if (s->dma_running) {
1371 1d14ffa9 bellard
        if (s->freq) {
1372 c0fe3827 bellard
            audsettings_t as;
1373 c0fe3827 bellard
1374 1d14ffa9 bellard
            s->audio_free = 0;
1375 c0fe3827 bellard
1376 c0fe3827 bellard
            as.freq = s->freq;
1377 c0fe3827 bellard
            as.nchannels = 1 << s->fmt_stereo;
1378 c0fe3827 bellard
            as.fmt = s->fmt;
1379 d929eba5 bellard
            as.endianness = 0;
1380 c0fe3827 bellard
1381 1d14ffa9 bellard
            s->voice = AUD_open_out (
1382 c0fe3827 bellard
                &s->card,
1383 1d14ffa9 bellard
                s->voice,
1384 1d14ffa9 bellard
                "sb16",
1385 1d14ffa9 bellard
                s,
1386 1d14ffa9 bellard
                SB_audio_callback,
1387 d929eba5 bellard
                &as
1388 1d14ffa9 bellard
                );
1389 1d14ffa9 bellard
        }
1390 85571bc7 bellard
1391 85571bc7 bellard
        control (s, 1);
1392 85571bc7 bellard
        speaker (s, s->speaker);
1393 d75d9f6b bellard
    }
1394 85571bc7 bellard
    return 0;
1395 d75d9f6b bellard
}
1396 d75d9f6b bellard
1397 d537cf6c pbrook
int SB16_init (AudioState *audio, qemu_irq *pic)
1398 27503323 bellard
{
1399 c0fe3827 bellard
    SB16State *s;
1400 27503323 bellard
    int i;
1401 27503323 bellard
    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1402 27503323 bellard
    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1403 27503323 bellard
1404 c0fe3827 bellard
    if (!audio) {
1405 c0fe3827 bellard
        dolog ("No audio state\n");
1406 c0fe3827 bellard
        return -1;
1407 c0fe3827 bellard
    }
1408 c0fe3827 bellard
1409 c0fe3827 bellard
    s = qemu_mallocz (sizeof (*s));
1410 c0fe3827 bellard
    if (!s) {
1411 a0d01ed9 bellard
        dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
1412 c0fe3827 bellard
               sizeof (*s));
1413 c0fe3827 bellard
        return -1;
1414 c0fe3827 bellard
    }
1415 c0fe3827 bellard
1416 1d14ffa9 bellard
    s->cmd = -1;
1417 d537cf6c pbrook
    s->pic = pic;
1418 85571bc7 bellard
    s->irq = conf.irq;
1419 85571bc7 bellard
    s->dma = conf.dma;
1420 85571bc7 bellard
    s->hdma = conf.hdma;
1421 85571bc7 bellard
    s->port = conf.port;
1422 85571bc7 bellard
    s->ver = conf.ver_lo | (conf.ver_hi << 8);
1423 202a456a bellard
1424 85571bc7 bellard
    s->mixer_regs[0x80] = magic_of_irq (s->irq);
1425 85571bc7 bellard
    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1426 85571bc7 bellard
    s->mixer_regs[0x82] = 2 << 5;
1427 85571bc7 bellard
1428 85571bc7 bellard
    s->csp_regs[5] = 1;
1429 85571bc7 bellard
    s->csp_regs[9] = 0xf8;
1430 85571bc7 bellard
1431 85571bc7 bellard
    reset_mixer (s);
1432 85571bc7 bellard
    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1433 1d14ffa9 bellard
    if (!s->aux_ts) {
1434 c0fe3827 bellard
        dolog ("warning: Could not create auxiliary timer\n");
1435 1d14ffa9 bellard
    }
1436 27503323 bellard
1437 27503323 bellard
    for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1438 85571bc7 bellard
        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1439 27503323 bellard
    }
1440 27503323 bellard
1441 27503323 bellard
    for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1442 85571bc7 bellard
        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1443 27503323 bellard
    }
1444 27503323 bellard
1445 85571bc7 bellard
    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1446 85571bc7 bellard
    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1447 85571bc7 bellard
    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1448 85571bc7 bellard
    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1449 27503323 bellard
1450 85571bc7 bellard
    DMA_register_channel (s->hdma, SB_read_DMA, s);
1451 85571bc7 bellard
    DMA_register_channel (s->dma, SB_read_DMA, s);
1452 85571bc7 bellard
    s->can_write = 1;
1453 d75d9f6b bellard
1454 85571bc7 bellard
    register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1455 c0fe3827 bellard
    AUD_register_card (audio, "sb16", &s->card);
1456 c0fe3827 bellard
    return 0;
1457 27503323 bellard
}