Revision 1d14ffa9 hw/sb16.c

b/hw/sb16.c
1 1
/*
2 2
 * QEMU Soundblaster 16 emulation
3
 * 
4
 * Copyright (c) 2003-2004 Vassili Karpov (malc)
5
 * 
3
 *
4
 * Copyright (c) 2003-2005 Vassili Karpov (malc)
5
 *
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
8 8
 * in the Software without restriction, including without limitation the rights
......
99 99
    int dma_running;
100 100
    int bytes_per_second;
101 101
    int align;
102
    SWVoice *voice;
102
    int audio_free;
103
    SWVoiceOut *voice;
103 104

  
104
    QEMUTimer *ts, *aux_ts;
105
    QEMUTimer *aux_ts;
105 106
    /* mixer state */
106 107
    int mixer_nreg;
107 108
    uint8_t mixer_regs[256];
......
110 111
/* XXX: suppress that and use a context */
111 112
static struct SB16State dsp;
112 113

  
114
static void SB_audio_callback (void *opaque, int free);
115

  
113 116
static int magic_of_irq (int irq)
114 117
{
115 118
    switch (irq) {
......
174 177

  
175 178
    if (hold) {
176 179
        DMA_hold_DREQ (dma);
177
        AUD_enable (s->voice, 1);
180
        AUD_set_active_out (s->voice, 1);
178 181
    }
179 182
    else {
180 183
        DMA_release_DREQ (dma);
181
        AUD_enable (s->voice, 0);
184
        AUD_set_active_out (s->voice, 0);
182 185
    }
183 186
}
184 187

  
......
207 210
        s->freq = (1000000 + (tmp / 2)) / tmp;
208 211
    }
209 212

  
210
    if (dma_len != -1)
213
    if (dma_len != -1) {
211 214
        s->block_size = dma_len << s->fmt_stereo;
215
    }
212 216
    else {
213 217
        /* This is apparently the only way to make both Act1/PL
214 218
           and SecondReality/FC work
......
227 231
    s->dma_auto = (mask & DMA8_AUTO) != 0;
228 232
    s->align = (1 << s->fmt_stereo) - 1;
229 233

  
230
    if (s->block_size & s->align)
231
        dolog ("warning: unaligned buffer\n");
234
    if (s->block_size & s->align) {
235
        dolog ("warning: misaligned block size %d, alignment %d\n",
236
               s->block_size, s->align + 1);
237
    }
232 238

  
233 239
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
234 240
            "dma %d, auto %d, fifo %d, high %d\n",
235 241
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
236 242
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
237 243

  
238
    if (s->freq)
239
        s->voice = AUD_open (s->voice, "sb16", s->freq,
240
                             1 << s->fmt_stereo, s->fmt);
244
    if (s->freq) {
245
        s->audio_free = 0;
246
        s->voice = AUD_open_out (
247
            s->voice,
248
            "sb16",
249
            s,
250
            SB_audio_callback,
251
            s->freq,
252
            1 << s->fmt_stereo,
253
            s->fmt
254
            );
255
    }
241 256

  
242 257
    control (s, 1);
243 258
    speaker (s, 1);
......
309 324
    s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
310 325
    s->highspeed = 0;
311 326
    s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
312
    if (s->block_size & s->align)
313
        dolog ("warning: unaligned buffer\n");
327
    if (s->block_size & s->align) {
328
        dolog ("warning: misaligned block size %d, alignment %d\n",
329
               s->block_size, s->align + 1);
330
    }
314 331

  
315
    if (s->freq)
316
        s->voice = AUD_open (s->voice, "sb16", s->freq,
317
                             1 << s->fmt_stereo, s->fmt);
332
    if (s->freq) {
333
        s->audio_free = 0;
334
        s->voice = AUD_open_out (
335
            s->voice,
336
            "sb16",
337
            s,
338
            SB_audio_callback,
339
            s->freq,
340
            1 << s->fmt_stereo,
341
            s->fmt
342
            );
343
    }
318 344

  
319 345
    control (s, 1);
320 346
    speaker (s, 1);
......
323 349
static inline void dsp_out_data (SB16State *s, uint8_t val)
324 350
{
325 351
    ldebug ("outdata %#x\n", val);
326
    if (s->out_data_len < sizeof (s->out_data))
352
    if (s->out_data_len < sizeof (s->out_data)) {
327 353
        s->out_data[s->out_data_len++] = val;
354
    }
328 355
}
329 356

  
330 357
static inline uint8_t dsp_get_data (SB16State *s)
331 358
{
332
    if (s->in_index)
359
    if (s->in_index) {
333 360
        return s->in2_data[--s->in_index];
361
    }
334 362
    else {
335 363
        dolog ("buffer underflow\n");
336 364
        return 0;
......
356 384
        s->needed_bytes = 3;
357 385
    }
358 386
    else {
387
        s->needed_bytes = 0;
388

  
359 389
        switch (cmd) {
360 390
        case 0x03:
361 391
            dsp_out_data (s, 0x10); /* s->csp_param); */
......
403 433
            goto warn;
404 434

  
405 435
        case 0x35:
406
            dolog ("MIDI command(0x35) not implemented\n");
436
            dolog ("0x35 - MIDI command not implemented\n");
407 437
            break;
408 438

  
409 439
        case 0x40:
......
435 465
            s->needed_bytes = 2;
436 466
            break;
437 467

  
468
        case 0x74:
469
            s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
470
            dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
471
            break;
472

  
473
        case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
474
            s->needed_bytes = 2;
475
            dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
476
            break;
477

  
478
        case 0x76:              /* DMA DAC, 2.6-bit ADPCM */
479
            s->needed_bytes = 2;
480
            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
481
            break;
482

  
483
        case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */
484
            s->needed_bytes = 2;
485
            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
486
            break;
487

  
488
        case 0x7d:
489
            dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
490
            dolog ("not implemented\n");
491
            break;
492

  
493
        case 0x7f:
494
            dolog (
495
                "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
496
                );
497
            dolog ("not implemented\n");
498
            break;
499

  
438 500
        case 0x80:
439 501
            s->needed_bytes = 2;
440 502
            break;
......
476 538
            s->dma_auto = 0;
477 539
            break;
478 540

  
479
        case 0xe0:
541
        case 0xe0:              /* DSP identification */
480 542
            s->needed_bytes = 1;
481
            goto warn;
543
            break;
482 544

  
483 545
        case 0xe1:
484 546
            dsp_out_data (s, s->ver & 0xff);
......
503 565

  
504 566
        case 0xe7:
505 567
            dolog ("Attempt to probe for ESS (0xe7)?\n");
506
            return;
568
            break;
507 569

  
508 570
        case 0xe8:              /* read test reg */
509 571
            dsp_out_data (s, s->test_reg);
......
529 591
            goto warn;
530 592

  
531 593
        default:
532
            dolog ("unrecognized command %#x\n", cmd);
533
            return;
594
            dolog ("Unrecognized command %#x\n", cmd);
595
            break;
534 596
        }
535 597
    }
536 598

  
537
    s->cmd = cmd;
538
    if (!s->needed_bytes)
599
    if (!s->needed_bytes) {
539 600
        ldebug ("\n");
601
    }
602

  
603
 exit:
604
    if (!s->needed_bytes) {
605
        s->cmd = -1;
606
    }
607
    else {
608
        s->cmd = cmd;
609
    }
540 610
    return;
541 611

  
542 612
 warn:
543 613
    dolog ("warning: command %#x,%d is not truly understood yet\n",
544 614
           cmd, s->needed_bytes);
545
    s->cmd = cmd;
546
    return;
615
    goto exit;
616

  
547 617
}
548 618

  
549 619
static uint16_t dsp_get_lohi (SB16State *s)
......
607 677
                s->csp_reg83[s->csp_reg83r % 4] = d0;
608 678
                s->csp_reg83r += 1;
609 679
            }
610
            else
680
            else {
611 681
                s->csp_regs[d1] = d0;
682
            }
612 683
            break;
613 684

  
614 685
        case 0x0f:
......
622 693
                dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
623 694
                s->csp_reg83w += 1;
624 695
            }
625
            else
696
            else {
626 697
                dsp_out_data (s, s->csp_regs[d0]);
698
            }
627 699
            break;
628 700

  
629 701
        case 0x10:
......
641 713
            break;
642 714

  
643 715
        case 0x42:              /* FT2 sets output freq with this, go figure */
716
#if 0
644 717
            dolog ("cmd 0x42 might not do what it think it should\n");
645

  
718
#endif
646 719
        case 0x41:
647 720
            s->freq = dsp_get_hilo (s);
648 721
            ldebug ("set freq %d\n", s->freq);
......
653 726
            ldebug ("set dma block len %d\n", s->block_size);
654 727
            break;
655 728

  
729
        case 0x74:
730
        case 0x75:
731
        case 0x76:
732
        case 0x77:
733
            /* ADPCM stuff, ignore */
734
            break;
735

  
656 736
        case 0x80:
657 737
            {
658 738
                int freq, samples, bytes;
......
662 742
                samples = dsp_get_lohi (s) + 1;
663 743
                bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
664 744
                ticks = (bytes * ticks_per_sec) / freq;
665
                if (ticks < ticks_per_sec / 1024)
745
                if (ticks < ticks_per_sec / 1024) {
666 746
                    pic_set_irq (s->irq, 1);
667
                else
668
                    qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
747
                }
748
                else {
749
                    if (s->aux_ts) {
750
                        qemu_mod_timer (
751
                            s->aux_ts,
752
                            qemu_get_clock (vm_clock) + ticks
753
                            );
754
                    }
755
                }
669 756
                ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
670 757
            }
671 758
            break;
......
674 761
            d0 = dsp_get_data (s);
675 762
            s->out_data_len = 0;
676 763
            ldebug ("E0 data = %#x\n", d0);
677
            dsp_out_data(s, ~d0);
764
            dsp_out_data (s, ~d0);
678 765
            break;
679 766

  
680 767
        case 0xe2:
......
737 824
    s->nzero = 0;
738 825
    s->highspeed = 0;
739 826
    s->v2x6 = 0;
827
    s->cmd = -1;
740 828

  
741 829
    dsp_out_data(s, 0xaa);
742 830
    speaker (s, 0);
......
761 849
                    pic_set_irq (s->irq, 0);
762 850
                    control (s, 0);
763 851
                }
764
                else
852
                else {
765 853
                    reset (s);
854
                }
766 855
            }
767 856
            s->v2x6 = 0;
768 857
            break;
......
845 934
            s->last_read_byte = retval;
846 935
        }
847 936
        else {
848
            dolog ("empty output buffer\n");
937
            if (s->cmd != -1) {
938
                dolog ("empty output buffer for command %#x\n",
939
                       s->cmd);
940
            }
849 941
            retval = s->last_read_byte;
850 942
            /* goto error; */
851 943
        }
......
882 974
        goto error;
883 975
    }
884 976

  
885
    if (!ack)
977
    if (!ack) {
886 978
        ldebug ("read %#x -> %#x\n", nport, retval);
979
    }
887 980

  
888 981
    return retval;
889 982

  
890 983
 error:
891
    dolog ("WARNING dsp_read %#x error\n", nport);
984
    dolog ("warning: dsp_read %#x error\n", nport);
892 985
    return 0xff;
893 986
}
894 987

  
......
933 1026
    SB16State *s = opaque;
934 1027

  
935 1028
    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
936
    if (s->mixer_nreg > sizeof (s->mixer_regs))
1029
    if (s->mixer_nreg > sizeof (s->mixer_regs)) {
937 1030
        return;
1031
    }
938 1032

  
939 1033
    switch (s->mixer_nreg) {
940 1034
    case 0x00:
......
945 1039
        {
946 1040
            int irq = irq_of_magic (val);
947 1041
            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
948
            if (irq > 0)
1042
            if (irq > 0) {
949 1043
                s->irq = irq;
1044
            }
950 1045
        }
951 1046
        break;
952 1047

  
......
956 1051

  
957 1052
            dma = lsbindex (val & 0xf);
958 1053
            hdma = lsbindex (val & 0xf0);
959
            dolog ("attempt to set DMA register 8bit %d, 16bit %d (val=%#x)\n",
960
                   dma, hdma, val);
1054
            if (dma != s->dma || hdma != s->hdma) {
1055
                dolog (
1056
                    "attempt to change DMA "
1057
                    "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1058
                    dma, s->dma, hdma, s->hdma, val);
1059
            }
961 1060
#if 0
962 1061
            s->dma = dma;
963 1062
            s->hdma = hdma;
......
971 1070
        return;
972 1071

  
973 1072
    default:
974
        if (s->mixer_nreg >= 0x80)
975
            dolog ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1073
        if (s->mixer_nreg >= 0x80) {
1074
            ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1075
        }
976 1076
        break;
977 1077
    }
978 1078

  
......
989 1089
{
990 1090
    SB16State *s = opaque;
991 1091
#ifndef DEBUG_SB16_MOST
992
    if (s->mixer_nreg != 0x82)
993
#endif
1092
    if (s->mixer_nreg != 0x82) {
1093
        ldebug ("mixer_read[%#x] -> %#x\n",
1094
                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1095
    }
1096
#else
994 1097
    ldebug ("mixer_read[%#x] -> %#x\n",
995 1098
            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1099
#endif
996 1100
    return s->mixer_regs[s->mixer_nreg];
997 1101
}
998 1102

  
......
1010 1114
        int to_copy, copied;
1011 1115

  
1012 1116
        to_copy = audio_MIN (temp, left);
1013
        if (to_copy > sizeof(tmpbuf))
1117
        if (to_copy > sizeof(tmpbuf)) {
1014 1118
            to_copy = sizeof(tmpbuf);
1119
        }
1015 1120

  
1016 1121
        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1017 1122
        copied = AUD_write (s->voice, tmpbuf, copied);
......
1020 1125
        dma_pos = (dma_pos + copied) % dma_len;
1021 1126
        net += copied;
1022 1127

  
1023
        if (!copied)
1128
        if (!copied) {
1024 1129
            break;
1130
        }
1025 1131
    }
1026 1132

  
1027 1133
    return net;
......
1030 1136
static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1031 1137
{
1032 1138
    SB16State *s = opaque;
1033
    int free, rfree, till, copy, written, elapsed;
1139
    int till, copy, written, free;
1034 1140

  
1035 1141
    if (s->left_till_irq < 0) {
1036 1142
        s->left_till_irq = s->block_size;
1037 1143
    }
1038 1144

  
1039
    elapsed = AUD_calc_elapsed (s->voice);
1040
    free = elapsed;/* AUD_get_free (s->voice); */
1041
    rfree = free;
1042
    free = audio_MIN (free, elapsed) & ~s->align;
1043

  
1044
    if ((free <= 0) || !dma_len) {
1045
        return dma_pos;
1145
    if (s->voice) {
1146
        free = s->audio_free & ~s->align;
1147
        if ((free <= 0) || !dma_len) {
1148
            return dma_pos;
1149
        }
1150
    }
1151
    else {
1152
        free = dma_len;
1046 1153
    }
1047 1154

  
1048 1155
    copy = free;
1049 1156
    till = s->left_till_irq;
1050 1157

  
1051 1158
#ifdef DEBUG_SB16_MOST
1052
    dolog ("pos:%06d free:%d,%d till:%d len:%d\n",
1053
           dma_pos, free, AUD_get_free (s->voice), till, dma_len);
1159
    dolog ("pos:%06d %d till:%d len:%d\n",
1160
           dma_pos, free, till, dma_len);
1054 1161
#endif
1055 1162

  
1056 1163
    if (till <= copy) {
......
1082 1189
        s->left_till_irq = s->block_size + s->left_till_irq;
1083 1190
    }
1084 1191

  
1085
    AUD_adjust (s->voice, written);
1086 1192
    return dma_pos;
1087 1193
}
1088 1194

  
1089
void SB_timer (void *opaque)
1195
static void SB_audio_callback (void *opaque, int free)
1090 1196
{
1091 1197
    SB16State *s = opaque;
1092
    AUD_run ();
1093
    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1198
    s->audio_free = free;
1094 1199
}
1095 1200

  
1096 1201
static void SB_save (QEMUFile *f, void *opaque)
......
1150 1255
{
1151 1256
    SB16State *s = opaque;
1152 1257

  
1153
    if (version_id != 1)
1258
    if (version_id != 1) {
1154 1259
        return -EINVAL;
1260
    }
1155 1261

  
1156 1262
    qemu_get_be32s (f, &s->irq);
1157 1263
    qemu_get_be32s (f, &s->dma);
......
1202 1308
    qemu_get_buffer (f, s->mixer_regs, 256);
1203 1309

  
1204 1310
    if (s->voice) {
1205
        AUD_close (s->voice);
1311
        AUD_close_out (s->voice);
1206 1312
        s->voice = NULL;
1207 1313
    }
1208 1314

  
1209 1315
    if (s->dma_running) {
1210
        if (s->freq)
1211
            s->voice = AUD_open (s->voice, "sb16", s->freq,
1212
                                 1 << s->fmt_stereo, s->fmt);
1316
        if (s->freq) {
1317
            s->audio_free = 0;
1318
            s->voice = AUD_open_out (
1319
                s->voice,
1320
                "sb16",
1321
                s,
1322
                SB_audio_callback,
1323
                s->freq,
1324
                1 << s->fmt_stereo,
1325
                s->fmt
1326
                );
1327
        }
1213 1328

  
1214 1329
        control (s, 1);
1215 1330
        speaker (s, s->speaker);
......
1224 1339
    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1225 1340
    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1226 1341

  
1227
    s->ts = qemu_new_timer (vm_clock, SB_timer, s);
1228
    if (!s->ts)
1229
        return;
1230

  
1342
    s->cmd = -1;
1231 1343
    s->irq = conf.irq;
1232 1344
    s->dma = conf.dma;
1233 1345
    s->hdma = conf.hdma;
......
1243 1355

  
1244 1356
    reset_mixer (s);
1245 1357
    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1246
    if (!s->aux_ts)
1247
        return;
1358
    if (!s->aux_ts) {
1359
        dolog ("Can not create auxiliary timer\n");
1360
    }
1248 1361

  
1249 1362
    for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1250 1363
        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
......
1263 1376
    DMA_register_channel (s->dma, SB_read_DMA, s);
1264 1377
    s->can_write = 1;
1265 1378

  
1266
    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1267 1379
    register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1268 1380
}

Also available in: Unified diff