//============================================================================= // Get Interwave (UltraSound PnP) configuration if any //============================================================================= static qboolean GUS_GetIWData(void) { char *Interwave,s[INI_STRING_SIZE]; FILE *IwFile; int CodecBase,CodecDma,i; Interwave=getenv("INTERWAVE"); if (Interwave==NULL) return(false); // Open IW.INI IwFile=ini_fopen(Interwave,"rt"); if (IwFile==NULL) return(false); // Read codec base and codec DMA ini_fgets(IwFile,"setup 0","CodecBase",s); sscanf(s,"%X",&CodecBase); ini_fgets(IwFile,"setup 0","DMA2",s); sscanf(s,"%i",&CodecDma); ini_fclose(IwFile); // Make sure numbers OK if (CodecBase==0 || CodecDma==0) return(false); CodecRegisterSelect=CodecBase; CodecData=CodecBase+1; CodecStatus=CodecBase+2; DmaChannel=CodecDma; // Make sure there is a CODEC at the CODEC base // Clear any pending IRQs dos_inportb(CodecStatus); dos_outportb(CodecStatus,0); // Wait for 'INIT' bit to clear for (i=0;i<0xFFFF;i++) if ((dos_inportb(CodecRegisterSelect) & 0x80) == 0) break; if (i==0xFFFF) return(false); // Get chip revision - can not be zero dos_outportb(CodecRegisterSelect,CODEC_MODE_AND_ID); if ((dos_inportb(CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) return(false); if ((dos_inportb(CodecData) & 0x0F) == 0) return(false); HaveCodec=1; Con_Printf("Sound Card is UltraSound PnP\n"); return(true); }
int ResetDSP(void) { volatile int i; dos_outportb(dsp_port + 6, 1); for (i=65536 ; i ; i--) ; dos_outportb(dsp_port + 6, 0); for (i=65536 ; i ; i--) { if (!(dos_inportb(dsp_port + 0xe) & 0x80)) continue; if (dos_inportb(dsp_port + 0xa) == 0xaa) break; } if (i) return 0; else return 1; }
static void TrapKey(void) { keybuf[keybuf_head] = dos_inportb(0x60); dos_outportb(0x20, 0x20); keybuf_head = (keybuf_head + 1) & (KEYBUF_SIZE-1); }
void Sys_Init(void) { MaskExceptions (); Sys_SetFPCW (); dos_outportb(0x43, 0x34); // set system timer to mode 2 dos_outportb(0x40, 0); // for the Sys_FloatTime() function dos_outportb(0x40, 0); Sys_InitFloatTime (); _go32_interrupt_stack_size = 4 * 1024;; _go32_rmcb_stack_size = 4 * 1024; }
static void Sys_Init (void) { MaskExceptions (); Sys_SetFPCW (); #if !USE_UCLOCK_TIME dos_outportb(0x43, 0x34); // set system timer to mode 2 dos_outportb(0x40, 0); // for the Sys_DoubleTime() function dos_outportb(0x40, 0); #endif /* ! USE_UCLOCK_TIME */ Sys_InitTime (); _go32_interrupt_stack_size = 4 * 1024; _go32_rmcb_stack_size = 4 * 1024; }
/* ================ Sys_DoubleTime ================ */ double Sys_DoubleTime ( void ) { int r; unsigned t, tick; double ft, time; static int sametimecount; Sys_PushFPCW_SetHigh (); //{static float t = 0; t=t+0.05; return t;} // DEBUG t = *(unsigned short*)real2ptr(0x46c) * 65536; dos_outportb(0x43, 0); // latch time r = dos_inportb(0x40); r |= dos_inportb(0x40) << 8; r = (r-1) & 0xffff; tick = *(unsigned short*)real2ptr(0x46c) * 65536; if ((tick != t) && (r & 0x8000)) t = tick; ft = (double) (t+(65536-r)) / 1193200.0; time = ft - oldtime; oldtime = ft; if (time < 0) { if (time > -3000.0) time = 0.0; else time += 3600.0; } curtime += time; if (curtime == lastcurtime) { sametimecount++; if (sametimecount > 100000) { curtime += 1.0; sametimecount = 0; } } else { sametimecount = 0; } lastcurtime = curtime; Sys_PopFPCW (); return curtime; }
void TrapKey(void) { // static int ctrl=0; keybuf[keybuf_head] = dos_inportb(0x60); dos_outportb(0x20, 0x20); /* if (scantokey[keybuf[keybuf_head]&0x7f] == K_CTRL) ctrl=keybuf[keybuf_head]&0x80; if (ctrl && scantokey[keybuf[keybuf_head]&0x7f] == 'c') Sys_Error("ctrl-c hit\n"); */ keybuf_head = (keybuf_head + 1) & (KEYBUF_SIZE-1); }
//============================================================================= // Programs the DMA controller to start DMAing in Auto-init mode //============================================================================= static void GUS_StartDMA(BYTE DmaChannel,short *dma_buffer,int count) { int mode; int RealAddr; RealAddr = ptr2real(dma_buffer); if (DmaChannel <= 3) { ModeReg = 0x0B; DisableReg = 0x0A; ClearReg = 0x0E; } else { ModeReg = 0xD6; DisableReg = 0xD4; ClearReg = 0xDC; } CountReg=CountRegs[DmaChannel]; AddrReg=AddrRegs[DmaChannel]; dos_outportb(DisableReg, DmaChannel | 4); // disable channel // set mode- see "undocumented pc", p.876 mode = (1<<6) // single-cycle +(0<<5) // address increment +(1<<4) // auto-init dma +(2<<2) // read +(DmaChannel & 0x03); // channel # dos_outportb(ModeReg, mode); // set page dos_outportb(PageRegs[DmaChannel], RealAddr >> 16); if (DmaChannel <= 3) { // address is in bytes dos_outportb(0x0C, 0); // prepare to send 16-bit value dos_outportb(AddrReg, RealAddr & 0xff); dos_outportb(AddrReg, (RealAddr>>8) & 0xff); dos_outportb(0x0C, 0); // prepare to send 16-bit value dos_outportb(CountReg, (count-1) & 0xff); dos_outportb(CountReg, (count-1) >> 8); }
void WriteDSP(int val) { while ((dos_inportb(dsp_port+0xc)&0x80)) ; dos_outportb(dsp_port+0xc, val); }
void SetGf116(BYTE reg,WORD data) { dos_outportb(Gf1RegisterSelect,reg); dos_outportw(Gf1DataLow,data); }
//============================================================================= // Get regular UltraSound configuration if any //============================================================================= static qboolean GUS_GetGUSData(void) { char *Ultrasnd; int GusBase,Dma1,Dma2,Irq1,Irq2,i; Ultrasnd=getenv("ULTRASND"); if (Ultrasnd==NULL) return(false); sscanf(Ultrasnd,"%x,%i,%i,%i,%i",&GusBase,&Dma1,&Dma2,&Irq1,&Irq2); DmaChannel=Dma1 & 0x07; // Make sure there is a GUS at GUS base dos_outportb(GusBase+0x08,0x55); if (dos_inportb(GusBase+0x0A)!=0x55) return(false); dos_outportb(GusBase+0x08,0xAA); if (dos_inportb(GusBase+0x0A)!=0xAA) return(false); Gf1TimerControl = GusBase+0x008; Gf1PageRegister = GusBase+0x102; Gf1RegisterSelect = GusBase+0x103; Gf1DataLow = GusBase+0x104; Gf1DataHigh = GusBase+0x105; // Reset the GUS SetGf18(MASTER_RESET,0x00); Gf1Delay(); Gf1Delay(); SetGf18(MASTER_RESET,0x01); Gf1Delay(); Gf1Delay(); // Set to max (32) voices SetGf18(SET_VOICES,0xDF); // Clear any pending IRQ's ClearGf1Ints(); // Set all registers to known values for (i=0;i<32;i++) { dos_outportb(Gf1PageRegister,i); SetGf18(SET_CONTROL,0x03); SetGf18(SET_VOLUME_CONTROL,0x03); Gf1Delay(); SetGf18(SET_CONTROL,0x03); SetGf18(SET_VOLUME_CONTROL,0x03); SetGf116(SET_START_HIGH,0); SetGf116(SET_START_LOW,0); SetGf116(SET_END_HIGH,0); SetGf116(SET_END_LOW,0); SetGf116(SET_ACC_HIGH,0); SetGf116(SET_ACC_LOW,0); SetGf18(SET_VOLUME_RATE,63); SetGf18(SET_VOLUME_START,5); SetGf18(SET_VOLUME_END,251); SetGf116(SET_VOLUME,5<<8); } // Clear any pending IRQ's ClearGf1Ints(); // Enable DAC etc. SetGf18(MASTER_RESET,0x07); // Enable line output so we can hear something dos_outportb(GusBase,0x08); HaveCodec=0; Con_Printf("Sound Card is UltraSound\n"); return(true); }
//============================================================================= // Get UltraSound MAX configuration if any //============================================================================= static qboolean GUS_GetMAXData(void) { char *Ultrasnd,*Ultra16; int i; int GusBase,Dma1,Dma2,Irq1,Irq2; int CodecBase,CodecDma,CodecIrq,CodecType; BYTE MaxVal; Ultrasnd=getenv("ULTRASND"); Ultra16=getenv("ULTRA16"); if (Ultrasnd==NULL || Ultra16==NULL) return(false); sscanf(Ultrasnd,"%x,%i,%i,%i,%i",&GusBase,&Dma1,&Dma2,&Irq1,&Irq2); sscanf(Ultra16,"%x,%i,%i,%i",&CodecBase,&CodecDma,&CodecIrq,&CodecType); if (CodecType==0 && CodecDma!=0) DmaChannel=CodecDma & 0x07; else DmaChannel=Dma2 & 0x07; // Make sure there is a GUS at GUS base dos_outportb(GusBase+0x08,0x55); if (dos_inportb(GusBase+0x0A)!=0x55) return(false); dos_outportb(GusBase+0x08,0xAA); if (dos_inportb(GusBase+0x0A)!=0xAA) return(false); // Program CODEC control register MaxVal=((CodecBase & 0xF0)>>4) | 0x40; if (Dma1 > 3) MaxVal|=0x10; if (Dma2 > 3) MaxVal|=0x20; dos_outportb(GusBase+0x106,MaxVal); CodecRegisterSelect=CodecBase; CodecData=CodecBase+1; CodecStatus=CodecBase+2; // Make sure there is a CODEC at the CODEC base // Clear any pending IRQs dos_inportb(CodecStatus); dos_outportb(CodecStatus,0); // Wait for 'INIT' bit to clear for (i=0;i<0xFFFF;i++) if ((dos_inportb(CodecRegisterSelect) & 0x80) == 0) break; if (i==0xFFFF) return(false); // Get chip revision - can not be zero dos_outportb(CodecRegisterSelect,CODEC_MODE_AND_ID); if ((dos_inportb(CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) return(false); if ((dos_inportb(CodecData) & 0x0F) == 0) return(false); HaveCodec=1; Con_Printf("Sound Card is UltraSound MAX\n"); return(true); }
WORD GetGf116(BYTE reg) { dos_outportb(Gf1RegisterSelect,reg); return(dos_inportw(Gf1DataLow)); }
BYTE GetGf18(BYTE reg) { dos_outportb(Gf1RegisterSelect,reg); return(dos_inportb(Gf1DataHigh)); }
int ReadMixer(int addr) { dos_outportb(mixer_port+4, addr); return dos_inportb(mixer_port+5); }
void WriteMixer(int addr, int val) { dos_outportb(mixer_port+4, addr); dos_outportb(mixer_port+5, val); }
//============================================================================= // Basic GF1 functions //============================================================================= void SetGf18(BYTE reg,BYTE data) { dos_outportb(Gf1RegisterSelect,reg); dos_outportb(Gf1DataHigh,data); }