home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 June B / Pcwk6b98.iso / Mpeg3 / Dos / MP3 / MPG12304.EXE / AUDIO.GUS < prev    next >
Text File  |  1997-05-05  |  15KB  |  701 lines

  1. #include <dos.h>
  2. #include "audio.h"
  3. #include "mpg123.h"
  4. #include "mdma.h"
  5. #include "mirq.h"
  6.  
  7. void UltraSetInterface(int,int,int,int);
  8. void GF1OutB(UBYTE,UBYTE);
  9. void GF1OutW(UBYTE,UWORD);
  10. UBYTE UltraPeek(ULONG);
  11. void interrupt far gf1handler(void);
  12. void gf1_delay(void);
  13. void UltraPoke(ULONG,UBYTE);
  14. BOOL UltraProbe(void);
  15. void UltraDisableOutput(void);
  16. void UltraDisableLineIn(void);
  17. void UltraDisableMicIn(void);
  18. BOOL UltraDetect(void);
  19. int next(int);
  20. UWORD UltraSizeDram();
  21. void ultrastop();
  22. void ultrastart();
  23. UBYTE GF1InB(UBYTE);
  24. void UltraReset(int);
  25. BOOL UltraPP(ULONG);
  26. void UltraClose();
  27. void UltraSetFrequency(ULONG);
  28. ULONG convert_to_16bit(ULONG);
  29. ULONG UltraReadVoice(UBYTE);
  30. ULONG make_physical_address(UWORD,UWORD,UBYTE);
  31. UWORD GF1InW(UBYTE);
  32.  
  33. UWORD GUS_PORT;
  34. UBYTE GUS_VOICES;
  35. UBYTE GUS_MIX_IMAGE;
  36.  
  37. UWORD GUS_DRAM_DMA;
  38. UWORD GUS_ADC_DMA;
  39. UWORD GUS_GF1_IRQ;
  40. UWORD GUS_MIDI_IRQ;
  41.  
  42. UBYTE GUS_SELECT;     /* currently selected GF1 register */
  43.  
  44. PVI oldhandler;
  45.  
  46. DMAMEM * dma_control;
  47.  
  48. static int store,play,playing;
  49. int bufs,memsize;
  50.  
  51. int audio_open(struct audio_info_struct *ai)
  52. {
  53.   UBYTE vmode,mode;
  54.  
  55.   if (ultradetect() == 0)
  56.   {
  57.     perror("Ultrasound not detected (sorry. SB support not finished)");
  58.     return -1;
  59.   }
  60.  
  61.   GUS_MIX_IMAGE=0x0b;
  62.  
  63.   UltraDisableLineIn();
  64.   UltraDisableMicIn();
  65.   UltraDisableOutput();
  66.  
  67.   UltraReset(14);
  68.  
  69.   if ((memsize=UltraSizeDram())==0)
  70.   {
  71.     perror("Go buy some memory for your GUS.");
  72.     return -1;
  73.   }
  74.  
  75.   oldhandler=MIrq_SetHandler(GUS_GF1_IRQ,gf1handler);
  76.   
  77.   MIrq_OnOff(GUS_GF1_IRQ,1);
  78.  
  79.   bufs=memsize/(AUDIOBUFSIZE*2/1024);
  80.   store=0;
  81.   play=0;
  82.   playing=2;
  83.  
  84.   outportb(GF1_VOICE_SELECT,0);
  85.  
  86.    GF1OutW(SET_START_HIGH,0);
  87.    GF1OutW(SET_START_LOW,0);
  88.  
  89.    vmode = VC_ROLLOVER|VOLUME_STOPPED|STOP_VOLUME;
  90.    GF1OutB(SET_VOLUME_CONTROL,vmode);
  91.    gf1_delay();
  92.    GF1OutB(SET_VOLUME_CONTROL,vmode);
  93.    
  94.    GF1OutB(SET_BALANCE,0);
  95.  
  96.    GF1OutW(SET_VOLUME,0xfff<<4);
  97.  
  98.    mode=(VC_DATA_TYPE|VOICE_STOPPED|STOP_VOICE);
  99.    GF1OutB(SET_CONTROL,mode);
  100.    gf1_delay();
  101.    GF1OutB(SET_CONTROL,mode);
  102.  
  103.   outportb(GF1_VOICE_SELECT,1);
  104.  
  105.    GF1OutW(SET_START_HIGH,ADDR_HIGH(convert_to_16bit(bufs*AUDIOBUFSIZE)));
  106.    GF1OutW(SET_START_LOW,ADDR_LOW(convert_to_16bit(bufs*AUDIOBUFSIZE)));
  107.  
  108.    vmode = VC_ROLLOVER|VOLUME_STOPPED|STOP_VOLUME;
  109.    GF1OutB(SET_VOLUME_CONTROL,vmode);
  110.    gf1_delay();
  111.    GF1OutB(SET_VOLUME_CONTROL,vmode);
  112.  
  113.    GF1OutB(SET_BALANCE,0xf);
  114.  
  115.    GF1OutW(SET_VOLUME,0xfff<<4);
  116.  
  117.    mode=(VOICE_STOPPED|STOP_VOICE|VC_DATA_TYPE);
  118.    GF1OutB(SET_CONTROL,mode);
  119.    gf1_delay();
  120.    GF1OutB(SET_CONTROL,mode);
  121.  
  122.   dma_control = MDma_AllocMem(AUDIOBUFSIZE);
  123.  
  124.   return 0;
  125. }
  126.  
  127. int audio_set_rate(struct audio_info_struct *ai)
  128. {
  129.   outportb(GF1_VOICE_SELECT,0);
  130.   UltraSetFrequency(ai->rate);
  131.   outportb(GF1_VOICE_SELECT,1);
  132.   UltraSetFrequency(ai->rate);
  133.   return 0;       
  134. }
  135.  
  136. int audio_set_channels(struct audio_info_struct *ai)
  137. {
  138.   return 0;       
  139. }
  140.  
  141. #define DMA_MODE ((GUS_DRAM_DMA>=4)?DMA_WIDTH_16:0)|DMA_DATA_16|DMA_READ
  142.  
  143. int audio_play_samples(struct audio_info_struct *ai,short *src,int size)
  144. {
  145.   char * ptr;
  146.   int c,s,addr;
  147.   char * dma_block;
  148.   dma_block = MDma_GetPtr(dma_control);
  149.  
  150.   fprintf(stderr,"playing %d, play %d, store %d, ltrue %d, rtrue %d        ",playing,play,store,UltraReadVoice(0)/AUDIOBUFSIZE,UltraReadVoice(1)/AUDIOBUFSIZE-bufs);
  151.  
  152.   if (playing != 2)
  153.     while (store == play)
  154.       if (playing == 0)
  155.         ultrastart();
  156.  
  157.   ptr=(char *) src;
  158.   addr=store*AUDIOBUFSIZE;
  159.  
  160.   for(c=0;c<size;c+=2,ptr+=4)
  161.   {
  162.     *(dma_block+c)=*(ptr);
  163.     *(dma_block+c+1)=*(ptr+1);
  164.   }
  165.  
  166.   GF1OutW(SET_DMA_ADDRESS,(addr>>4));
  167.   GF1OutB(DMA_CONTROL,DMA_MODE);
  168.  
  169.   MDma_Start(GUS_DRAM_DMA,dma_control,size,WRITE_DMA);
  170.  
  171.   GF1OutB(DMA_CONTROL,DMA_MODE|DMA_ENABLE);
  172.  
  173.   while (MDma_ToDo(GUS_DRAM_DMA)<AUDIOBUFSIZE);
  174.  
  175.   MDma_Stop(GUS_DRAM_DMA);
  176.  
  177.   ptr=(char *) src;
  178.   addr=store*AUDIOBUFSIZE+bufs*AUDIOBUFSIZE;
  179.  
  180.   for(c=0;c<size;c+=2,ptr+=4)
  181.   {
  182.     *(dma_block+c)=*(ptr+2);
  183.     *(dma_block+c+1)=*(ptr+3);
  184.   }
  185.  
  186.   GF1OutW(SET_DMA_ADDRESS,(addr)>>4);
  187.  
  188.   GF1OutB(DMA_CONTROL,DMA_MODE);
  189.  
  190.   MDma_Start(GUS_DRAM_DMA,dma_control,size,WRITE_DMA);
  191.  
  192.   GF1OutB(DMA_CONTROL,DMA_MODE|DMA_ENABLE);
  193.  
  194.   while (MDma_ToDo(GUS_DRAM_DMA)<AUDIOBUFSIZE);
  195.  
  196.   MDma_Stop(GUS_DRAM_DMA);
  197.  
  198.   store=next(store);
  199.   if (playing == 2)
  200.     playing=0;
  201.  
  202.   return 0;
  203. }
  204.  
  205. int audio_close(struct audio_info_struct *ai)
  206. {
  207.   UltraClose();
  208.   MDma_FreeMem(dma_control);
  209.   return 0;
  210. }
  211.  
  212. static void interrupt far gf1handler(MIRQARGS)
  213. {
  214.   ULONG phys_end;
  215.   UBYTE oldselect=GUS_SELECT;
  216.   UBYTE mode;
  217.  
  218.   inportb(GF1_IRQ_STAT);
  219.   GF1InB(GET_IRQV);
  220.  
  221.   play=next(play);
  222.  
  223.   outportb(GF1_VOICE_SELECT,0);
  224.   phys_end   = convert_to_16bit(play*AUDIOBUFSIZE+AUDIOBUFSIZE-1);
  225.   GF1OutW(SET_END_HIGH,ADDR_HIGH(phys_end));
  226.   GF1OutW(SET_END_LOW,ADDR_LOW(phys_end));
  227.  
  228.   outportb(GF1_VOICE_SELECT,1);
  229.   phys_end   = convert_to_16bit(bufs*AUDIOBUFSIZE+play*AUDIOBUFSIZE+AUDIOBUFSIZE-1);
  230.   GF1OutW(SET_END_HIGH,ADDR_HIGH(phys_end));
  231.   GF1OutW(SET_END_LOW,ADDR_LOW(phys_end));
  232.  
  233.   if (play == bufs-1)
  234.   {
  235.     outportb(GF1_VOICE_SELECT,0);
  236.     mode=(VC_WAVE_IRQ|VC_DATA_TYPE|VC_LOOP_ENABLE);
  237.     GF1OutB(SET_CONTROL,mode);
  238.     gf1_delay();
  239.     GF1OutB(SET_CONTROL,mode);
  240.  
  241.     outportb(GF1_VOICE_SELECT,1);
  242.     mode=(VC_DATA_TYPE|VC_LOOP_ENABLE);
  243.     GF1OutB(SET_CONTROL,mode);
  244.     gf1_delay();
  245.     GF1OutB(SET_CONTROL,mode);
  246.   }
  247.   else
  248.   {
  249.     outportb(GF1_VOICE_SELECT,0);
  250.     mode=(VC_WAVE_IRQ|VC_DATA_TYPE);
  251.     GF1OutB(SET_CONTROL,mode);
  252.     gf1_delay();
  253.     GF1OutB(SET_CONTROL,mode);
  254.  
  255.     outportb(GF1_VOICE_SELECT,1);
  256.     mode=(VC_DATA_TYPE);
  257.     GF1OutB(SET_CONTROL,mode);
  258.     gf1_delay();
  259.     GF1OutB(SET_CONTROL,mode);
  260.   }
  261.  
  262.   if (play == store)
  263.   {
  264.     ultrastop();
  265.   }
  266.  
  267.   UltraSelect(oldselect);
  268.   MIrq_EOI(GUS_GF1_IRQ);
  269. }
  270.  
  271. void UltraReset(int voices)
  272. {
  273.     int v;
  274.  
  275.     if(voices<14) voices=14;
  276.     if(voices>32) voices=32;
  277.  
  278.     GUS_VOICES=voices;
  279.  
  280.     GF1OutB(MASTER_RESET,0x00);
  281.  
  282.     for(v=0;v<10;v++) gf1_delay();
  283.  
  284.     GF1OutB(MASTER_RESET,GF1_MASTER_RESET);
  285.  
  286.     for (v=0;v<10;v++) gf1_delay();
  287.  
  288.   outportb(GF1_MIDI_CTRL,MIDI_RESET);
  289.  
  290.     for (v=0;v<10;v++) gf1_delay();
  291.  
  292.      outportb(GF1_MIDI_CTRL,0x00);
  293.  
  294.     for (v=0;v<10;v++) gf1_delay();
  295.  
  296.   UltraSetInterface(GUS_DRAM_DMA,GUS_ADC_DMA,GUS_GF1_IRQ,GUS_MIDI_IRQ);
  297.  
  298.     /* Clear all interrupts. */
  299.     GF1OutB(DMA_CONTROL,0x00);
  300.     GF1OutB(TIMER_CONTROL,0x00);
  301.     GF1OutB(SAMPLE_CONTROL,0x00);
  302.  
  303.     /* Set the number of active voices */
  304.     GF1OutB(SET_VOICES,((voices-1) | 0xC0));
  305.  
  306.     /* Clear interrupts on voices. */
  307.     /* Reading the status ports will clear the irqs. */
  308.  
  309.     inportb(GF1_IRQ_STAT);
  310.     GF1InB(DMA_CONTROL);
  311.     GF1InB(SAMPLE_CONTROL);
  312.     GF1InB(GET_IRQV);
  313.  
  314.     for(v=0;v<voices;v++){
  315.  
  316.         outportb(GF1_PAGE,v);
  317.  
  318.         GF1OutB(SET_CONTROL,VOICE_STOPPED|STOP_VOICE);
  319.         GF1OutB(SET_VOLUME_CONTROL,VOLUME_STOPPED|STOP_VOLUME);
  320.  
  321.         gf1_delay(); /* Wait 4.8 micos. or more. */
  322.  
  323.     GF1OutW(SET_FREQUENCY,0x0400);
  324.         GF1OutW(SET_START_HIGH,0);
  325.         GF1OutW(SET_START_LOW,0);
  326.         GF1OutW(SET_END_HIGH,0);
  327.         GF1OutW(SET_END_LOW,0);
  328.         GF1OutB(SET_VOLUME_RATE,0x01);
  329.         GF1OutB(SET_VOLUME_START,0x10);
  330.         GF1OutB(SET_VOLUME_END,0xe0);
  331.         GF1OutW(SET_VOLUME,0x0000);
  332.  
  333.         GF1OutW(SET_ACC_HIGH,0);
  334.         GF1OutW(SET_ACC_LOW,0);
  335.         GF1OutB(SET_BALANCE,0x07);
  336.     }
  337.  
  338.     inportb(GF1_IRQ_STAT);
  339.  
  340.     GF1InB(DMA_CONTROL);
  341.     GF1InB(SAMPLE_CONTROL);
  342.     GF1InB(GET_IRQV);
  343.  
  344.     GF1OutB(MASTER_RESET,GF1_MASTER_RESET|GF1_OUTPUT_ENABLE|GF1_MASTER_IRQ);
  345. }
  346.  
  347. UWORD UltraSizeDram(void)
  348. {
  349.     if(!UltraPP(0))      return 0;
  350.     if(!UltraPP(262144)) return 256;
  351.     if(!UltraPP(524288)) return 512;
  352.     if(!UltraPP(786432)) return 768;
  353.     return 1024;
  354. }
  355.  
  356. UBYTE GF1InB(UBYTE x)
  357. {
  358.     UltraSelect(x);
  359.     return inportb(GF1_DATA_HI);
  360. }
  361.  
  362. BOOL UltraPP(ULONG address)
  363. {
  364.     UBYTE s,t;
  365.     s=UltraPeek(address);
  366.     UltraPoke(address,0xaa);
  367.     t=UltraPeek(address);
  368.     UltraPoke(address,s);
  369.     return(t==0xaa);
  370. }
  371.  
  372. void UltraClose(void)
  373. {
  374.     MIrq_OnOff(GUS_GF1_IRQ,0);
  375.     MIrq_SetHandler(GUS_GF1_IRQ,oldhandler);
  376.     UltraDisableOutput();
  377.     UltraDisableLineIn();
  378.     UltraDisableMicIn();
  379.     UltraReset(14);
  380. }
  381.  
  382. void UltraSetFrequency(ULONG speed_khz)
  383. {
  384. //  GF1OutW(SET_FREQUENCY,(((speed_khz<<9L)+(44100>>1L))/44100)<<1);
  385.   GF1OutW(SET_FREQUENCY,(int)(((float)speed_khz)/43.0243902439));
  386. }
  387.  
  388. void ultrastop()
  389. {
  390.   UBYTE mode;
  391.  
  392.   outportb(GF1_VOICE_SELECT,0);
  393.   mode=VC_DATA_TYPE|VOICE_STOPPED|STOP_VOICE;
  394.  
  395.   GF1OutB(SET_CONTROL,mode);
  396.   gf1_delay();
  397.   GF1OutB(SET_CONTROL,mode);
  398.   
  399.   outportb(GF1_VOICE_SELECT,1);
  400.   mode=VC_DATA_TYPE|VOICE_STOPPED|STOP_VOICE;
  401.  
  402.   GF1OutB(SET_CONTROL,mode);
  403.   gf1_delay();
  404.   GF1OutB(SET_CONTROL,mode);
  405.  
  406.   playing=0;
  407. }
  408.  
  409. void ultrastart()
  410. {
  411.   ULONG phys_end;
  412.   ULONG phys_begin;
  413.   UBYTE mode;
  414.  
  415.   outportb(GF1_VOICE_SELECT,0);
  416.   phys_begin = convert_to_16bit(play*AUDIOBUFSIZE);
  417.   phys_end   = convert_to_16bit(play*AUDIOBUFSIZE+AUDIOBUFSIZE-1);
  418.  
  419.   GF1OutW(SET_ACC_LOW,ADDR_LOW(phys_begin));
  420.   GF1OutW(SET_ACC_HIGH,ADDR_HIGH(phys_begin));
  421.  
  422.   GF1OutW(SET_END_HIGH,ADDR_HIGH(phys_end));
  423.   GF1OutW(SET_END_LOW,ADDR_LOW(phys_end));
  424.  
  425.   outportb(GF1_VOICE_SELECT,1);
  426.   phys_begin = convert_to_16bit(play*AUDIOBUFSIZE+bufs*AUDIOBUFSIZE);
  427.   phys_end   = convert_to_16bit(play*AUDIOBUFSIZE+bufs*AUDIOBUFSIZE+AUDIOBUFSIZE-1);
  428.  
  429.   GF1OutW(SET_ACC_LOW,ADDR_LOW(phys_begin));
  430.   GF1OutW(SET_ACC_HIGH,ADDR_HIGH(phys_begin));
  431.  
  432.   GF1OutW(SET_END_HIGH,ADDR_HIGH(phys_end));
  433.   GF1OutW(SET_END_LOW,ADDR_LOW(phys_end));
  434.  
  435.   outportb(GF1_VOICE_SELECT,0);
  436.  
  437.   mode=(VC_WAVE_IRQ|VC_DATA_TYPE);
  438.   GF1OutB(SET_CONTROL,mode);
  439.   gf1_delay();
  440.   GF1OutB(SET_CONTROL,mode);
  441.  
  442.   outportb(GF1_VOICE_SELECT,1);
  443.  
  444.   mode=(VC_DATA_TYPE);
  445.   GF1OutB(SET_CONTROL,mode);
  446.   gf1_delay();
  447.   GF1OutB(SET_CONTROL,mode);
  448.  
  449.   if (play == bufs-1)
  450.   {
  451.     outportb(GF1_VOICE_SELECT,0);
  452.     mode=(VC_WAVE_IRQ|VC_DATA_TYPE|VC_LOOP_ENABLE);
  453.     GF1OutB(SET_CONTROL,mode);
  454.     gf1_delay();
  455.     GF1OutB(SET_CONTROL,mode);
  456.  
  457.     outportb(GF1_VOICE_SELECT,1);
  458.     mode=(VC_DATA_TYPE|VC_LOOP_ENABLE);
  459.     GF1OutB(SET_CONTROL,mode);
  460.     gf1_delay();
  461.     GF1OutB(SET_CONTROL,mode);
  462.   }
  463.  
  464.   playing=1;
  465. }
  466.  
  467. ULONG convert_to_16bit(ULONG address)
  468. /* unsigned long address;         /* 20 bit ultrasound dram address */
  469. {
  470.     ULONG hold_address;
  471.  
  472.     hold_address = address;
  473.  
  474.     /* Convert to 16 translated address. */
  475.     address = address >> 1;
  476.  
  477.     /* Zero out bit 17. */
  478.     address &= 0x0001ffffL;
  479.  
  480.     /* Reset bits 18 and 19. */
  481.     address |= (hold_address & 0x000c0000L);
  482.  
  483.     return(address);
  484. }
  485.  
  486. void GF1OutB(UBYTE x,UBYTE y)
  487. {
  488.     UltraSelect(x);
  489.     outportb(GF1_DATA_HI,y);
  490. }
  491.  
  492. void GF1OutW(UBYTE x,UWORD y)
  493. {
  494.     UltraSelect(x);
  495.     outport(GF1_DATA_LOW,y);
  496. }
  497.  
  498. UBYTE UltraPeek(ULONG address)
  499. {
  500.     GF1OutW(SET_DRAM_LOW,address);
  501.     GF1OutB(SET_DRAM_HIGH,(address>>16)&0xff);      /* 8 bits */
  502.     return(inportb(GF1_DRAM));
  503. }
  504.  
  505. void gf1_delay(void)
  506. {
  507.     inportb(GF1_DRAM);
  508.     inportb(GF1_DRAM);
  509.     inportb(GF1_DRAM);
  510.     inportb(GF1_DRAM);
  511.     inportb(GF1_DRAM);
  512.     inportb(GF1_DRAM);
  513.     inportb(GF1_DRAM);
  514. }
  515.  
  516. void UltraPoke(ULONG address,UBYTE data)
  517. {
  518.   GF1OutW(SET_DRAM_LOW,(short)address&0xffff);
  519.     GF1OutB(SET_DRAM_HIGH,(address>>16)&0xff);
  520.     outportb(GF1_DRAM,data);
  521. }
  522.  
  523. BOOL UltraProbe(void)
  524. {
  525.     UBYTE s1,s2,t1,t2;
  526.  
  527.     /* Pull a reset on the GF1 */
  528.  
  529.     GF1OutB(MASTER_RESET,0x00);
  530.  
  531.     /* Wait a little while ... */
  532.     gf1_delay();
  533.     gf1_delay();
  534.  
  535.     /* Release Reset */
  536.     GF1OutB(MASTER_RESET,GF1_MASTER_RESET);
  537.  
  538.     gf1_delay();
  539.     gf1_delay();
  540.  
  541.     s1=UltraPeek(0); s2=UltraPeek(1);
  542.     UltraPoke(0,0xaa); t1=UltraPeek(0);
  543.     UltraPoke(1,0x55); t2=UltraPeek(1);
  544.     UltraPoke(0,s1); UltraPoke(1,s2);
  545.  
  546.     return(t1==0xaa && t2==0x55);
  547. }
  548.  
  549. void UltraDisableOutput(void)
  550. {
  551.     GUS_MIX_IMAGE |= ENABLE_OUTPUT;
  552.     outportb(GF1_MIX_CTRL,GUS_MIX_IMAGE);
  553. }
  554.  
  555. void UltraDisableLineIn(void)
  556. {
  557.     GUS_MIX_IMAGE |= ENABLE_LINE_IN;
  558.     outportb(GF1_MIX_CTRL,GUS_MIX_IMAGE);
  559. }
  560.  
  561. void UltraDisableMicIn(void)
  562. {
  563.     GUS_MIX_IMAGE &= ~ENABLE_MIC_IN;
  564.     outportb(GF1_MIX_CTRL,GUS_MIX_IMAGE);
  565. }
  566.  
  567. BOOL UltraDetect(void)
  568. {
  569.   char * pointa;
  570.  
  571.   pointa=(char *)getenv("ULTRASND");
  572.   if(pointa==0) return 0;
  573.  
  574.   if(sscanf(pointa,"%hx,%hd,%hd,%hd,%hd",
  575.                 &GUS_PORT,
  576.                 &GUS_DRAM_DMA,
  577.                 &GUS_ADC_DMA,
  578.                 &GUS_GF1_IRQ,
  579.                 &GUS_MIDI_IRQ)!=5) return 0;
  580.  
  581.   return(UltraProbe());
  582. }
  583.  
  584.  
  585. int next(int supa)
  586. {
  587.   if (supa+1 == bufs)
  588.     return 0;
  589.   return (supa+1);
  590. }
  591.  
  592. UBYTE dmalatch[8]       ={ 0,1,0,2,0,3,4,5 };
  593. UBYTE irqlatch[16]      ={ 0,0,1,3,0,2,0,4,0,0,0,5,6,0,0,7 };
  594.  
  595. void UltraSetInterface(int dram,int adc,int gf1,int midi)
  596. /* int dram;    /* dram dma chan */
  597. /* int adc;       /* adc dma chan */
  598. /* int gf1;       /* gf1 irq # */
  599. /* int midi;    /* midi irq # */
  600. {
  601.     UBYTE gf1_irq, midi_irq,dram_dma,adc_dma;
  602.     UBYTE irq_control,dma_control;
  603.     UBYTE mix_image;
  604.  
  605.     /* Don't need to check for 0 irq #. Its latch entry = 0 */
  606.     gf1_irq =irqlatch[gf1];
  607.     midi_irq=irqlatch[midi];
  608.     midi_irq<<=3;
  609.  
  610.     dram_dma=dmalatch[dram];
  611.     adc_dma =dmalatch[adc];
  612.     adc_dma<<=3;
  613.  
  614.     irq_control=dma_control=0x0;
  615.  
  616.     mix_image=GUS_MIX_IMAGE;
  617.  
  618.     irq_control|=gf1_irq;
  619.  
  620.     if((gf1==midi) && (gf1!=0))
  621.         irq_control|=0x40;
  622.     else
  623.         irq_control|=midi_irq;
  624.  
  625.     dma_control|=dram_dma;
  626.  
  627.     if((dram==adc) && (dram!=0))
  628.         dma_control|=0x40;
  629.     else
  630.         dma_control|=adc_dma;
  631.  
  632.     /* Set up for Digital ASIC */
  633.     outportb(GUS_PORT+0x0f,0x5);
  634.     outportb(GF1_MIX_CTRL,mix_image);
  635.     outportb(GF1_IRQ_CTRL,0x0);
  636.     outportb(GUS_PORT+0x0f,0x0);
  637.  
  638.     /* First do DMA control register */
  639.     outportb(GF1_MIX_CTRL,mix_image);
  640.     outportb(GF1_IRQ_CTRL,dma_control|0x80);
  641.  
  642.     /* IRQ CONTROL REG */
  643.     outportb(GF1_MIX_CTRL,mix_image|0x40);
  644.     outportb(GF1_IRQ_CTRL,irq_control);
  645.  
  646.     /* First do DMA control register */
  647.     outportb(GF1_MIX_CTRL,mix_image);
  648.     outportb(GF1_IRQ_CTRL,dma_control);
  649.  
  650.     /* IRQ CONTROL REG */
  651.     outportb(GF1_MIX_CTRL,mix_image|0x40);
  652.     outportb(GF1_IRQ_CTRL,irq_control);
  653.  
  654.     /* IRQ CONTROL, ENABLE IRQ */
  655.     /* just to Lock out writes to irq\dma register ... */
  656.     outportb(GF1_VOICE_SELECT,0);
  657.  
  658.     /* enable output & irq, disable line & mic input */
  659.     mix_image|=0x09;
  660.     outportb(GF1_MIX_CTRL,mix_image);
  661.  
  662.     /* just to Lock out writes to irq\dma register ... */
  663.     outportb(GF1_VOICE_SELECT,0x0);
  664.  
  665.     /* put image back .... */
  666.     GUS_MIX_IMAGE=mix_image;
  667. }
  668.  
  669. ULONG UltraReadVoice(UBYTE voice)
  670. {
  671.   outportb(GF1_VOICE_SELECT,voice);
  672.   return(make_physical_address(GF1InW(GET_ACC_LOW),GF1InW(GET_ACC_HIGH),GF1InB(GET_CONTROL))&0xfffffL);
  673. }
  674.  
  675. ULONG make_physical_address(UWORD low,UWORD high,UBYTE mode)
  676. {
  677.     UWORD lower_16, upper_16;
  678.     ULONG ret_address, bit_19_20;
  679.  
  680.     upper_16 = high >> 9;
  681.     lower_16 = ((high & 0x01ff) << 7) | ((low >> 9) & 0x007f);
  682.  
  683.     ret_address = MAKE_MS_SWORD(upper_16) + lower_16;
  684.  
  685.     if (mode & VC_DATA_TYPE)
  686.         {
  687.         bit_19_20 = ret_address & 0xC0000;
  688.         ret_address <<= 1;
  689.         ret_address &= 0x3ffff;
  690.         ret_address |= bit_19_20;
  691.         }
  692.  
  693.     return( ret_address );
  694. }
  695.  
  696. UWORD GF1InW(UBYTE x)
  697. {
  698.     UltraSelect(x);
  699.     return inport(GF1_DATA_LOW);
  700. }
  701.