/[qemu]/qemu/hw/sb16.c
ViewVC logotype

Diff of /qemu/hw/sb16.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.15 by bellard, Sun Aug 21 09:30:54 2005 UTC revision 1.16 by bellard, Sun Oct 30 18:58:22 2005 UTC
# Line 1  Line 1 
1  /*  /*
2   * QEMU Soundblaster 16 emulation   * QEMU Soundblaster 16 emulation
3   *   *
4   * Copyright (c) 2003-2004 Vassili Karpov (malc)   * Copyright (c) 2003-2005 Vassili Karpov (malc)
5   *   *
6   * Permission is hereby granted, free of charge, to any person obtaining a copy   * Permission is hereby granted, free of charge, to any person obtaining a copy
7   * of this software and associated documentation files (the "Software"), to deal   * of this software and associated documentation files (the "Software"), to deal
8   * in the Software without restriction, including without limitation the rights   * in the Software without restriction, including without limitation the rights
# Line 99  typedef struct SB16State { Line 99  typedef struct SB16State {
99      int dma_running;      int dma_running;
100      int bytes_per_second;      int bytes_per_second;
101      int align;      int align;
102      SWVoice *voice;      int audio_free;
103        SWVoiceOut *voice;
104    
105      QEMUTimer *ts, *aux_ts;      QEMUTimer *aux_ts;
106      /* mixer state */      /* mixer state */
107      int mixer_nreg;      int mixer_nreg;
108      uint8_t mixer_regs[256];      uint8_t mixer_regs[256];
# Line 110  typedef struct SB16State { Line 111  typedef struct SB16State {
111  /* XXX: suppress that and use a context */  /* XXX: suppress that and use a context */
112  static struct SB16State dsp;  static struct SB16State dsp;
113    
114    static void SB_audio_callback (void *opaque, int free);
115    
116  static int magic_of_irq (int irq)  static int magic_of_irq (int irq)
117  {  {
118      switch (irq) {      switch (irq) {
# Line 174  static void control (SB16State *s, int h Line 177  static void control (SB16State *s, int h
177    
178      if (hold) {      if (hold) {
179          DMA_hold_DREQ (dma);          DMA_hold_DREQ (dma);
180          AUD_enable (s->voice, 1);          AUD_set_active_out (s->voice, 1);
181      }      }
182      else {      else {
183          DMA_release_DREQ (dma);          DMA_release_DREQ (dma);
184          AUD_enable (s->voice, 0);          AUD_set_active_out (s->voice, 0);
185      }      }
186  }  }
187    
# Line 207  static void dma_cmd8 (SB16State *s, int Line 210  static void dma_cmd8 (SB16State *s, int
210          s->freq = (1000000 + (tmp / 2)) / tmp;          s->freq = (1000000 + (tmp / 2)) / tmp;
211      }      }
212    
213      if (dma_len != -1)      if (dma_len != -1) {
214          s->block_size = dma_len << s->fmt_stereo;          s->block_size = dma_len << s->fmt_stereo;
215        }
216      else {      else {
217          /* This is apparently the only way to make both Act1/PL          /* This is apparently the only way to make both Act1/PL
218             and SecondReality/FC work             and SecondReality/FC work
# Line 227  static void dma_cmd8 (SB16State *s, int Line 231  static void dma_cmd8 (SB16State *s, int
231      s->dma_auto = (mask & DMA8_AUTO) != 0;      s->dma_auto = (mask & DMA8_AUTO) != 0;
232      s->align = (1 << s->fmt_stereo) - 1;      s->align = (1 << s->fmt_stereo) - 1;
233    
234      if (s->block_size & s->align)      if (s->block_size & s->align) {
235          dolog ("warning: unaligned buffer\n");          dolog ("warning: misaligned block size %d, alignment %d\n",
236                   s->block_size, s->align + 1);
237        }
238    
239      ldebug ("freq %d, stereo %d, sign %d, bits %d, "      ldebug ("freq %d, stereo %d, sign %d, bits %d, "
240              "dma %d, auto %d, fifo %d, high %d\n",              "dma %d, auto %d, fifo %d, high %d\n",
241              s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,              s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
242              s->block_size, s->dma_auto, s->fifo, s->highspeed);              s->block_size, s->dma_auto, s->fifo, s->highspeed);
243    
244      if (s->freq)      if (s->freq) {
245          s->voice = AUD_open (s->voice, "sb16", s->freq,          s->audio_free = 0;
246                               1 << s->fmt_stereo, s->fmt);          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        }
256    
257      control (s, 1);      control (s, 1);
258      speaker (s, 1);      speaker (s, 1);
# Line 309  static void dma_cmd (SB16State *s, uint8 Line 324  static void dma_cmd (SB16State *s, uint8
324      s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);      s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
325      s->highspeed = 0;      s->highspeed = 0;
326      s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;      s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
327      if (s->block_size & s->align)      if (s->block_size & s->align) {
328          dolog ("warning: unaligned buffer\n");          dolog ("warning: misaligned block size %d, alignment %d\n",
329                   s->block_size, s->align + 1);
330      if (s->freq)      }
331          s->voice = AUD_open (s->voice, "sb16", s->freq,  
332                               1 << s->fmt_stereo, s->fmt);      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        }
344    
345      control (s, 1);      control (s, 1);
346      speaker (s, 1);      speaker (s, 1);
# Line 323  static void dma_cmd (SB16State *s, uint8 Line 349  static void dma_cmd (SB16State *s, uint8
349  static inline void dsp_out_data (SB16State *s, uint8_t val)  static inline void dsp_out_data (SB16State *s, uint8_t val)
350  {  {
351      ldebug ("outdata %#x\n", val);      ldebug ("outdata %#x\n", val);
352      if (s->out_data_len < sizeof (s->out_data))      if (s->out_data_len < sizeof (s->out_data)) {
353          s->out_data[s->out_data_len++] = val;          s->out_data[s->out_data_len++] = val;
354        }
355  }  }
356    
357  static inline uint8_t dsp_get_data (SB16State *s)  static inline uint8_t dsp_get_data (SB16State *s)
358  {  {
359      if (s->in_index)      if (s->in_index) {
360          return s->in2_data[--s->in_index];          return s->in2_data[--s->in_index];
361        }
362      else {      else {
363          dolog ("buffer underflow\n");          dolog ("buffer underflow\n");
364          return 0;          return 0;
# Line 356  static void command (SB16State *s, uint8 Line 384  static void command (SB16State *s, uint8
384          s->needed_bytes = 3;          s->needed_bytes = 3;
385      }      }
386      else {      else {
387            s->needed_bytes = 0;
388    
389          switch (cmd) {          switch (cmd) {
390          case 0x03:          case 0x03:
391              dsp_out_data (s, 0x10); /* s->csp_param); */              dsp_out_data (s, 0x10); /* s->csp_param); */
# Line 403  static void command (SB16State *s, uint8 Line 433  static void command (SB16State *s, uint8
433              goto warn;              goto warn;
434    
435          case 0x35:          case 0x35:
436              dolog ("MIDI command(0x35) not implemented\n");              dolog ("0x35 - MIDI command not implemented\n");
437              break;              break;
438    
439          case 0x40:          case 0x40:
# Line 435  static void command (SB16State *s, uint8 Line 465  static void command (SB16State *s, uint8
465              s->needed_bytes = 2;              s->needed_bytes = 2;
466              break;              break;
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    
500          case 0x80:          case 0x80:
501              s->needed_bytes = 2;              s->needed_bytes = 2;
502              break;              break;
# Line 476  static void command (SB16State *s, uint8 Line 538  static void command (SB16State *s, uint8
538              s->dma_auto = 0;              s->dma_auto = 0;
539              break;              break;
540    
541          case 0xe0:          case 0xe0:              /* DSP identification */
542              s->needed_bytes = 1;              s->needed_bytes = 1;
543              goto warn;              break;
544    
545          case 0xe1:          case 0xe1:
546              dsp_out_data (s, s->ver & 0xff);              dsp_out_data (s, s->ver & 0xff);
# Line 503  static void command (SB16State *s, uint8 Line 565  static void command (SB16State *s, uint8
565    
566          case 0xe7:          case 0xe7:
567              dolog ("Attempt to probe for ESS (0xe7)?\n");              dolog ("Attempt to probe for ESS (0xe7)?\n");
568              return;              break;
569    
570          case 0xe8:              /* read test reg */          case 0xe8:              /* read test reg */
571              dsp_out_data (s, s->test_reg);              dsp_out_data (s, s->test_reg);
# Line 529  static void command (SB16State *s, uint8 Line 591  static void command (SB16State *s, uint8
591              goto warn;              goto warn;
592    
593          default:          default:
594              dolog ("unrecognized command %#x\n", cmd);              dolog ("Unrecognized command %#x\n", cmd);
595              return;              break;
596          }          }
597      }      }
598    
599      s->cmd = cmd;      if (!s->needed_bytes) {
     if (!s->needed_bytes)  
600          ldebug ("\n");          ldebug ("\n");
601        }
602    
603     exit:
604        if (!s->needed_bytes) {
605            s->cmd = -1;
606        }
607        else {
608            s->cmd = cmd;
609        }
610      return;      return;
611    
612   warn:   warn:
613      dolog ("warning: command %#x,%d is not truly understood yet\n",      dolog ("warning: command %#x,%d is not truly understood yet\n",
614             cmd, s->needed_bytes);             cmd, s->needed_bytes);
615      s->cmd = cmd;      goto exit;
616      return;  
617  }  }
618    
619  static uint16_t dsp_get_lohi (SB16State *s)  static uint16_t dsp_get_lohi (SB16State *s)
# Line 607  static void complete (SB16State *s) Line 677  static void complete (SB16State *s)
677                  s->csp_reg83[s->csp_reg83r % 4] = d0;                  s->csp_reg83[s->csp_reg83r % 4] = d0;
678                  s->csp_reg83r += 1;                  s->csp_reg83r += 1;
679              }              }
680              else              else {
681                  s->csp_regs[d1] = d0;                  s->csp_regs[d1] = d0;
682                }
683              break;              break;
684    
685          case 0x0f:          case 0x0f:
# Line 622  static void complete (SB16State *s) Line 693  static void complete (SB16State *s)
693                  dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);                  dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
694                  s->csp_reg83w += 1;                  s->csp_reg83w += 1;
695              }              }
696              else              else {
697                  dsp_out_data (s, s->csp_regs[d0]);                  dsp_out_data (s, s->csp_regs[d0]);
698                }
699              break;              break;
700    
701          case 0x10:          case 0x10:
# Line 641  static void complete (SB16State *s) Line 713  static void complete (SB16State *s)
713              break;              break;
714    
715          case 0x42:              /* FT2 sets output freq with this, go figure */          case 0x42:              /* FT2 sets output freq with this, go figure */
716    #if 0
717              dolog ("cmd 0x42 might not do what it think it should\n");              dolog ("cmd 0x42 might not do what it think it should\n");
718    #endif
719          case 0x41:          case 0x41:
720              s->freq = dsp_get_hilo (s);              s->freq = dsp_get_hilo (s);
721              ldebug ("set freq %d\n", s->freq);              ldebug ("set freq %d\n", s->freq);
# Line 653  static void complete (SB16State *s) Line 726  static void complete (SB16State *s)
726              ldebug ("set dma block len %d\n", s->block_size);              ldebug ("set dma block len %d\n", s->block_size);
727              break;              break;
728    
729            case 0x74:
730            case 0x75:
731            case 0x76:
732            case 0x77:
733                /* ADPCM stuff, ignore */
734                break;
735    
736          case 0x80:          case 0x80:
737              {              {
738                  int freq, samples, bytes;                  int freq, samples, bytes;
# Line 662  static void complete (SB16State *s) Line 742  static void complete (SB16State *s)
742                  samples = dsp_get_lohi (s) + 1;                  samples = dsp_get_lohi (s) + 1;
743                  bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);                  bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
744                  ticks = (bytes * ticks_per_sec) / freq;                  ticks = (bytes * ticks_per_sec) / freq;
745                  if (ticks < ticks_per_sec / 1024)                  if (ticks < ticks_per_sec / 1024) {
746                      pic_set_irq (s->irq, 1);                      pic_set_irq (s->irq, 1);
747                  else                  }
748                      qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);                  else {
749                        if (s->aux_ts) {
750                            qemu_mod_timer (
751                                s->aux_ts,
752                                qemu_get_clock (vm_clock) + ticks
753                                );
754                        }
755                    }
756                  ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);                  ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
757              }              }
758              break;              break;
# Line 674  static void complete (SB16State *s) Line 761  static void complete (SB16State *s)
761              d0 = dsp_get_data (s);              d0 = dsp_get_data (s);
762              s->out_data_len = 0;              s->out_data_len = 0;
763              ldebug ("E0 data = %#x\n", d0);              ldebug ("E0 data = %#x\n", d0);
764              dsp_out_data(s, ~d0);              dsp_out_data (s, ~d0);
765              break;              break;
766    
767          case 0xe2:          case 0xe2:
# Line 737  static void reset (SB16State *s) Line 824  static void reset (SB16State *s)
824      s->nzero = 0;      s->nzero = 0;
825      s->highspeed = 0;      s->highspeed = 0;
826      s->v2x6 = 0;      s->v2x6 = 0;
827        s->cmd = -1;
828    
829      dsp_out_data(s, 0xaa);      dsp_out_data(s, 0xaa);
830      speaker (s, 0);      speaker (s, 0);
# Line 761  static IO_WRITE_PROTO (dsp_write) Line 849  static IO_WRITE_PROTO (dsp_write)
849                      pic_set_irq (s->irq, 0);                      pic_set_irq (s->irq, 0);
850                      control (s, 0);                      control (s, 0);
851                  }                  }
852                  else                  else {
853                      reset (s);                      reset (s);
854                    }
855              }              }
856              s->v2x6 = 0;              s->v2x6 = 0;
857              break;              break;
# Line 845  static IO_READ_PROTO (dsp_read) Line 934  static IO_READ_PROTO (dsp_read)
934              s->last_read_byte = retval;              s->last_read_byte = retval;
935          }          }
936          else {          else {
937              dolog ("empty output buffer\n");              if (s->cmd != -1) {
938                    dolog ("empty output buffer for command %#x\n",
939                           s->cmd);
940                }
941              retval = s->last_read_byte;              retval = s->last_read_byte;
942              /* goto error; */              /* goto error; */
943          }          }
# Line 882  static IO_READ_PROTO (dsp_read) Line 974  static IO_READ_PROTO (dsp_read)
974          goto error;          goto error;
975      }      }
976    
977      if (!ack)      if (!ack) {
978          ldebug ("read %#x -> %#x\n", nport, retval);          ldebug ("read %#x -> %#x\n", nport, retval);
979        }
980    
981      return retval;      return retval;
982    
983   error:   error:
984      dolog ("WARNING dsp_read %#x error\n", nport);      dolog ("warning: dsp_read %#x error\n", nport);
985      return 0xff;      return 0xff;
986  }  }
987    
# Line 933  static IO_WRITE_PROTO(mixer_write_datab) Line 1026  static IO_WRITE_PROTO(mixer_write_datab)
1026      SB16State *s = opaque;      SB16State *s = opaque;
1027    
1028      ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);      ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1029      if (s->mixer_nreg > sizeof (s->mixer_regs))      if (s->mixer_nreg > sizeof (s->mixer_regs)) {
1030          return;          return;
1031        }
1032    
1033      switch (s->mixer_nreg) {      switch (s->mixer_nreg) {
1034      case 0x00:      case 0x00:
# Line 945  static IO_WRITE_PROTO(mixer_write_datab) Line 1039  static IO_WRITE_PROTO(mixer_write_datab)
1039          {          {
1040              int irq = irq_of_magic (val);              int irq = irq_of_magic (val);
1041              ldebug ("setting irq to %d (val=%#x)\n", irq, val);              ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1042              if (irq > 0)              if (irq > 0) {
1043                  s->irq = irq;                  s->irq = irq;
1044                }
1045          }          }
1046          break;          break;
1047    
# Line 956  static IO_WRITE_PROTO(mixer_write_datab) Line 1051  static IO_WRITE_PROTO(mixer_write_datab)
1051    
1052              dma = lsbindex (val & 0xf);              dma = lsbindex (val & 0xf);
1053              hdma = lsbindex (val & 0xf0);              hdma = lsbindex (val & 0xf0);
1054              dolog ("attempt to set DMA register 8bit %d, 16bit %d (val=%#x)\n",              if (dma != s->dma || hdma != s->hdma) {
1055                     dma, hdma, val);                  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                }
1060  #if 0  #if 0
1061              s->dma = dma;              s->dma = dma;
1062              s->hdma = hdma;              s->hdma = hdma;
# Line 971  static IO_WRITE_PROTO(mixer_write_datab) Line 1070  static IO_WRITE_PROTO(mixer_write_datab)
1070          return;          return;
1071    
1072      default:      default:
1073          if (s->mixer_nreg >= 0x80)          if (s->mixer_nreg >= 0x80) {
1074              dolog ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);              ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1075            }
1076          break;          break;
1077      }      }
1078    
# Line 989  static IO_READ_PROTO(mixer_read) Line 1089  static IO_READ_PROTO(mixer_read)
1089  {  {
1090      SB16State *s = opaque;      SB16State *s = opaque;
1091  #ifndef DEBUG_SB16_MOST  #ifndef DEBUG_SB16_MOST
1092      if (s->mixer_nreg != 0x82)      if (s->mixer_nreg != 0x82) {
1093  #endif          ldebug ("mixer_read[%#x] -> %#x\n",
1094                    s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1095        }
1096    #else
1097      ldebug ("mixer_read[%#x] -> %#x\n",      ldebug ("mixer_read[%#x] -> %#x\n",
1098              s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);              s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1099    #endif
1100      return s->mixer_regs[s->mixer_nreg];      return s->mixer_regs[s->mixer_nreg];
1101  }  }
1102    
# Line 1010  static int write_audio (SB16State *s, in Line 1114  static int write_audio (SB16State *s, in
1114          int to_copy, copied;          int to_copy, copied;
1115    
1116          to_copy = audio_MIN (temp, left);          to_copy = audio_MIN (temp, left);
1117          if (to_copy > sizeof(tmpbuf))          if (to_copy > sizeof(tmpbuf)) {
1118              to_copy = sizeof(tmpbuf);              to_copy = sizeof(tmpbuf);
1119            }
1120    
1121          copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);          copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1122          copied = AUD_write (s->voice, tmpbuf, copied);          copied = AUD_write (s->voice, tmpbuf, copied);
# Line 1020  static int write_audio (SB16State *s, in Line 1125  static int write_audio (SB16State *s, in
1125          dma_pos = (dma_pos + copied) % dma_len;          dma_pos = (dma_pos + copied) % dma_len;
1126          net += copied;          net += copied;
1127    
1128          if (!copied)          if (!copied) {
1129              break;              break;
1130            }
1131      }      }
1132    
1133      return net;      return net;
# Line 1030  static int write_audio (SB16State *s, in Line 1136  static int write_audio (SB16State *s, in
1136  static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)  static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1137  {  {
1138      SB16State *s = opaque;      SB16State *s = opaque;
1139      int free, rfree, till, copy, written, elapsed;      int till, copy, written, free;
1140    
1141      if (s->left_till_irq < 0) {      if (s->left_till_irq < 0) {
1142          s->left_till_irq = s->block_size;          s->left_till_irq = s->block_size;
1143      }      }
1144    
1145      elapsed = AUD_calc_elapsed (s->voice);      if (s->voice) {
1146      free = elapsed;/* AUD_get_free (s->voice); */          free = s->audio_free & ~s->align;
1147      rfree = free;          if ((free <= 0) || !dma_len) {
1148      free = audio_MIN (free, elapsed) & ~s->align;              return dma_pos;
1149            }
1150      if ((free <= 0) || !dma_len) {      }
1151          return dma_pos;      else {
1152            free = dma_len;
1153      }      }
1154    
1155      copy = free;      copy = free;
1156      till = s->left_till_irq;      till = s->left_till_irq;
1157    
1158  #ifdef DEBUG_SB16_MOST  #ifdef DEBUG_SB16_MOST
1159      dolog ("pos:%06d free:%d,%d till:%d len:%d\n",      dolog ("pos:%06d %d till:%d len:%d\n",
1160             dma_pos, free, AUD_get_free (s->voice), till, dma_len);             dma_pos, free, till, dma_len);
1161  #endif  #endif
1162    
1163      if (till <= copy) {      if (till <= copy) {
# Line 1082  static int SB_read_DMA (void *opaque, in Line 1189  static int SB_read_DMA (void *opaque, in
1189          s->left_till_irq = s->block_size + s->left_till_irq;          s->left_till_irq = s->block_size + s->left_till_irq;
1190      }      }
1191    
     AUD_adjust (s->voice, written);  
1192      return dma_pos;      return dma_pos;
1193  }  }
1194    
1195  void SB_timer (void *opaque)  static void SB_audio_callback (void *opaque, int free)
1196  {  {
1197      SB16State *s = opaque;      SB16State *s = opaque;
1198      AUD_run ();      s->audio_free = free;
     qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);  
1199  }  }
1200    
1201  static void SB_save (QEMUFile *f, void *opaque)  static void SB_save (QEMUFile *f, void *opaque)
# Line 1150  static int SB_load (QEMUFile *f, void *o Line 1255  static int SB_load (QEMUFile *f, void *o
1255  {  {
1256      SB16State *s = opaque;      SB16State *s = opaque;
1257    
1258      if (version_id != 1)      if (version_id != 1) {
1259          return -EINVAL;          return -EINVAL;
1260        }
1261    
1262      qemu_get_be32s (f, &s->irq);      qemu_get_be32s (f, &s->irq);
1263      qemu_get_be32s (f, &s->dma);      qemu_get_be32s (f, &s->dma);
# Line 1202  static int SB_load (QEMUFile *f, void *o Line 1308  static int SB_load (QEMUFile *f, void *o
1308      qemu_get_buffer (f, s->mixer_regs, 256);      qemu_get_buffer (f, s->mixer_regs, 256);
1309    
1310      if (s->voice) {      if (s->voice) {
1311          AUD_close (s->voice);          AUD_close_out (s->voice);
1312          s->voice = NULL;          s->voice = NULL;
1313      }      }
1314    
1315      if (s->dma_running) {      if (s->dma_running) {
1316          if (s->freq)          if (s->freq) {
1317              s->voice = AUD_open (s->voice, "sb16", s->freq,              s->audio_free = 0;
1318                                   1 << s->fmt_stereo, s->fmt);              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            }
1328    
1329          control (s, 1);          control (s, 1);
1330          speaker (s, s->speaker);          speaker (s, s->speaker);
# Line 1224  void SB16_init (void) Line 1339  void SB16_init (void)
1339      static const uint8_t dsp_write_ports[] = {0x6, 0xc};      static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1340      static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};      static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1341    
1342      s->ts = qemu_new_timer (vm_clock, SB_timer, s);      s->cmd = -1;
     if (!s->ts)  
         return;  
   
1343      s->irq = conf.irq;      s->irq = conf.irq;
1344      s->dma = conf.dma;      s->dma = conf.dma;
1345      s->hdma = conf.hdma;      s->hdma = conf.hdma;
# Line 1243  void SB16_init (void) Line 1355  void SB16_init (void)
1355    
1356      reset_mixer (s);      reset_mixer (s);
1357      s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);      s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1358      if (!s->aux_ts)      if (!s->aux_ts) {
1359          return;          dolog ("Can not create auxiliary timer\n");
1360        }
1361    
1362      for (i = 0; i < LENOFA (dsp_write_ports); i++) {      for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1363          register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);          register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
# Line 1263  void SB16_init (void) Line 1376  void SB16_init (void)
1376      DMA_register_channel (s->dma, SB_read_DMA, s);      DMA_register_channel (s->dma, SB_read_DMA, s);
1377      s->can_write = 1;      s->can_write = 1;
1378    
     qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);  
1379      register_savevm ("sb16", 0, 1, SB_save, SB_load, s);      register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1380  }  }

Legend:
Removed from v.1.15  
changed lines
  Added in v.1.16

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26