/[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.13 by bellard, Thu Nov 11 16:55:09 2004 UTC revision 1.14 by bellard, Sun Nov 14 16:02:09 2004 UTC
# Line 26  Line 26 
26  #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))  #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
27    
28  #define dolog(...) AUD_log ("sb16", __VA_ARGS__)  #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
29    
30    /* #define DEBUG */
31    /* #define DEBUG_SB16_MOST */
32    
33  #ifdef DEBUG  #ifdef DEBUG
34  #define ldebug(...) dolog (__VA_ARGS__)  #define ldebug(...) dolog (__VA_ARGS__)
35  #else  #else
36  #define ldebug(...)  #define ldebug(...)
37  #endif  #endif
38    
 /* #define DEBUG */  
 /* #define DEBUG_SB16_MOST */  
   
39  #define IO_READ_PROTO(name)                             \  #define IO_READ_PROTO(name)                             \
40      uint32_t name (void *opaque, uint32_t nport)      uint32_t name (void *opaque, uint32_t nport)
41  #define IO_WRITE_PROTO(name)                                    \  #define IO_WRITE_PROTO(name)                                    \
# Line 206  static void dma_cmd8 (SB16State *s, int Line 207  static void dma_cmd8 (SB16State *s, int
207          s->freq = (1000000 + (tmp / 2)) / tmp;          s->freq = (1000000 + (tmp / 2)) / tmp;
208      }      }
209    
210      if (-1 != dma_len)      if (dma_len != -1)
211          s->block_size = dma_len + 1;          s->block_size = dma_len << s->fmt_stereo;
212        else {
213            /* This is apparently the only way to make both Act1/PL
214               and SecondReality/FC work
215    
216               Act1 sets block size via command 0x48 and it's an odd number
217               SR does the same with even number
218               Both use stereo, and Creatives own documentation states that
219               0x48 sets block size in bytes less one.. go figure */
220            s->block_size &= ~s->fmt_stereo;
221        }
222    
223      s->freq >>= s->fmt_stereo;      s->freq >>= s->fmt_stereo;
224      s->left_till_irq = s->block_size;      s->left_till_irq = s->block_size;
# Line 216  static void dma_cmd8 (SB16State *s, int Line 227  static void dma_cmd8 (SB16State *s, int
227      s->dma_auto = (mask & DMA8_AUTO) != 0;      s->dma_auto = (mask & DMA8_AUTO) != 0;
228      s->align = (1 << s->fmt_stereo) - 1;      s->align = (1 << s->fmt_stereo) - 1;
229    
230        if (s->block_size & s->align)
231            dolog ("warning: unaligned buffer\n");
232    
233      ldebug ("freq %d, stereo %d, sign %d, bits %d, "      ldebug ("freq %d, stereo %d, sign %d, bits %d, "
234              "dma %d, auto %d, fifo %d, high %d\n",              "dma %d, auto %d, fifo %d, high %d\n",
235              s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,              s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
# Line 260  static void dma_cmd (SB16State *s, uint8 Line 274  static void dma_cmd (SB16State *s, uint8
274    
275      s->block_size = dma_len + 1;      s->block_size = dma_len + 1;
276      s->block_size <<= (s->fmt_bits == 16);      s->block_size <<= (s->fmt_bits == 16);
277      if (!s->dma_auto)           /* Miles Sound System ? */      if (!s->dma_auto) {
278            /* It is clear that for DOOM and auto-init this value
279               shouldn't take stereo into account, while Miles Sound Systems
280               setsound.exe with single transfer mode wouldn't work without it
281               wonders of SB16 yet again */
282          s->block_size <<= s->fmt_stereo;          s->block_size <<= s->fmt_stereo;
283        }
284    
285      ldebug ("freq %d, stereo %d, sign %d, bits %d, "      ldebug ("freq %d, stereo %d, sign %d, bits %d, "
286              "dma %d, auto %d, fifo %d, high %d\n",              "dma %d, auto %d, fifo %d, high %d\n",
# Line 290  static void dma_cmd (SB16State *s, uint8 Line 309  static void dma_cmd (SB16State *s, uint8
309      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);
310      s->highspeed = 0;      s->highspeed = 0;
311      s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;      s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
312        if (s->block_size & s->align)
313            dolog ("warning: unaligned buffer\n");
314    
315      if (s->freq)      if (s->freq)
316          s->voice = AUD_open (s->voice, "sb16", s->freq,          s->voice = AUD_open (s->voice, "sb16", s->freq,
# Line 373  static void command (SB16State *s, uint8 Line 394  static void command (SB16State *s, uint8
394              s->block_size = 0;              s->block_size = 0;
395              break;              break;
396    
397            case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
398                control (s, 1);
399                break;
400    
401          case 0x20:              /* Direct ADC, Juice/PL */          case 0x20:              /* Direct ADC, Juice/PL */
402              dsp_out_data (s, 0xff);              dsp_out_data (s, 0xff);
403              goto warn;              goto warn;
# Line 607  static void complete (SB16State *s) Line 632  static void complete (SB16State *s)
632              break;              break;
633    
634          case 0x14:          case 0x14:
635              dma_cmd8 (s, 0, dsp_get_lohi (s));              dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
             /* s->can_write = 0; */  
             /* qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + (ticks_per_sec * 320) / 1000000); */  
636              break;              break;
637    
638          case 0x40:          case 0x40:
# Line 626  static void complete (SB16State *s) Line 649  static void complete (SB16State *s)
649              break;              break;
650    
651          case 0x48:          case 0x48:
652              s->block_size = dsp_get_lohi (s);              s->block_size = dsp_get_lohi (s) + 1;
             /* s->highspeed = 1; */  
653              ldebug ("set dma block len %d\n", s->block_size);              ldebug ("set dma block len %d\n", s->block_size);
654              break;              break;
655    
656          case 0x80:          case 0x80:
657              {              {
658                  int samples, bytes;                  int freq, samples, bytes;
659                  int64_t ticks;                  int64_t ticks;
660    
661                  if (-1 == s->freq)                  freq = s->freq > 0 ? s->freq : 11025;
662                      s->freq = 11025;                  samples = dsp_get_lohi (s) + 1;
                 samples = dsp_get_lohi (s);  
663                  bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);                  bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
664                  ticks = bytes ? (ticks_per_sec / (s->freq / bytes)) : 0;                  ticks = (bytes * ticks_per_sec) / freq;
665                  if (!bytes || ticks < ticks_per_sec / 1024)                  if (ticks < ticks_per_sec / 1024)
666                      pic_set_irq (s->irq, 1);                      pic_set_irq (s->irq, 1);
667                  else                  else
668                      qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);                      qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
# Line 658  static void complete (SB16State *s) Line 679  static void complete (SB16State *s)
679    
680          case 0xe2:          case 0xe2:
681              d0 = dsp_get_data (s);              d0 = dsp_get_data (s);
682              dolog ("E2 = %#x\n", d0);              ldebug ("E2 = %#x\n", d0);
683              break;              break;
684    
685          case 0xe4:          case 0xe4:
# Line 967  static IO_WRITE_PROTO(mixer_write_indexw Line 988  static IO_WRITE_PROTO(mixer_write_indexw
988  static IO_READ_PROTO(mixer_read)  static IO_READ_PROTO(mixer_read)
989  {  {
990      SB16State *s = opaque;      SB16State *s = opaque;
991    #ifndef DEBUG_SB16_MOST
992        if (s->mixer_nreg != 0x82)
993    #endif
994      ldebug ("mixer_read[%#x] -> %#x\n",      ldebug ("mixer_read[%#x] -> %#x\n",
995              s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);              s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
996      return s->mixer_regs[s->mixer_nreg];      return s->mixer_regs[s->mixer_nreg];
# Line 1049  static int SB_read_DMA (void *opaque, in Line 1073  static int SB_read_DMA (void *opaque, in
1073      }      }
1074    
1075  #ifdef DEBUG_SB16_MOST  #ifdef DEBUG_SB16_MOST
1076      ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",      ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1077              dma_pos, free, dma_len, s->left_till_irq, copy, s->block_size);              dma_pos, free, dma_len, s->left_till_irq, copy, written,
1078                s->block_size);
1079  #endif  #endif
1080    
1081      while (s->left_till_irq <= 0) {      while (s->left_till_irq <= 0) {

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

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