home *** CD-ROM | disk | FTP | other *** search
/ modiromppu / modiromppu.iso / PROGRAMS / ORGPACKS / MPG12304.ZIP / AUDIO.N < prev    next >
Text File  |  1997-04-30  |  15KB  |  706 lines

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