?? id_sd.c
字號:
// Turn SB Pro stereo DAC off
sbOut(sbpMixerAddr,sbpmControl);
sbOut(sbpMixerData,0); // 0=off,2=on
}
}
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_ShutSB() - Turns off the SoundBlaster
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_ShutSB(void)
{
SDL_SBStopSample();
if (SBProPresent)
{
// Restore FM output levels (SB Pro)
sbOut(sbpMixerAddr,sbpmFMVol);
sbOut(sbpMixerData,sbpOldFMMix);
// Restore Voice output levels (SB Pro)
sbOut(sbpMixerAddr,sbpmVoiceVol);
sbOut(sbpMixerData,sbpOldVOCMix);
}
setvect(sbIntVec,sbOldIntHand); // Set vector back
}
// Sound Source Code
///////////////////////////////////////////////////////////////////////////
//
// SDL_SSStopSample() - Stops a sample playing on the Sound Source
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_SSStopSample(void)
{
asm pushf
asm cli
(long)ssSample = 0;
asm popf
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_SSService() - Handles playing the next sample on the Sound Source
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_SSService(void)
{
boolean gotit;
byte v;
while (ssSample)
{
asm mov dx,[ssStatus] // Check to see if FIFO is currently empty
asm in al,dx
asm test al,0x40
asm jnz done // Nope - don't push any more data out
v = *ssSample++;
if (!(--ssLengthLeft))
{
(long)ssSample = 0;
SDL_DigitizedDone();
}
asm mov dx,[ssData] // Pump the value out
asm mov al,[v]
asm out dx,al
asm mov dx,[ssControl] // Pulse printer select
asm mov al,[ssOff]
asm out dx,al
asm push ax
asm pop ax
asm mov al,[ssOn]
asm out dx,al
asm push ax // Delay a short while
asm pop ax
asm push ax
asm pop ax
}
done:;
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_SSPlaySample() - Plays the specified sample on the Sound Source
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_SSPlaySample(byte huge *data,longword len)
{
asm pushf
asm cli
ssLengthLeft = len;
ssSample = (volatile byte far *)data;
asm popf
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_StartSS() - Sets up for and turns on the Sound Source
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_StartSS(void)
{
if (ssPort == 3)
ssControl = 0x27a; // If using LPT3
else if (ssPort == 2)
ssControl = 0x37a; // If using LPT2
else
ssControl = 0x3be; // If using LPT1
ssStatus = ssControl - 1;
ssData = ssStatus - 1;
ssOn = 0x04;
if (ssIsTandy)
ssOff = 0x0e; // Tandy wierdness
else
ssOff = 0x0c; // For normal machines
outportb(ssControl,ssOn); // Enable SS
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_ShutSS() - Turns off the Sound Source
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_ShutSS(void)
{
outportb(ssControl,ssOff);
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_CheckSS() - Checks to see if a Sound Source is present at the
// location specified by the sound source variables
//
///////////////////////////////////////////////////////////////////////////
static boolean
SDL_CheckSS(void)
{
boolean present = false;
longword lasttime;
// Turn the Sound Source on and wait awhile (4 ticks)
SDL_StartSS();
lasttime = TimeCount;
while (TimeCount < lasttime + 4)
;
asm mov dx,[ssStatus] // Check to see if FIFO is currently empty
asm in al,dx
asm test al,0x40
asm jnz checkdone // Nope - Sound Source not here
asm mov cx,32 // Force FIFO overflow (FIFO is 16 bytes)
outloop:
asm mov dx,[ssData] // Pump a neutral value out
asm mov al,0x80
asm out dx,al
asm mov dx,[ssControl] // Pulse printer select
asm mov al,[ssOff]
asm out dx,al
asm push ax
asm pop ax
asm mov al,[ssOn]
asm out dx,al
asm push ax // Delay a short while before we do this again
asm pop ax
asm push ax
asm pop ax
asm loop outloop
asm mov dx,[ssStatus] // Is FIFO overflowed now?
asm in al,dx
asm test al,0x40
asm jz checkdone // Nope, still not - Sound Source not here
present = true; // Yes - it's here!
checkdone:
SDL_ShutSS();
return(present);
}
static boolean
SDL_DetectSoundSource(void)
{
for (ssPort = 1;ssPort <= 3;ssPort++)
if (SDL_CheckSS())
return(true);
return(false);
}
//
// PC Sound code
//
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCPlaySample() - Plays the specified sample on the PC speaker
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_PCPlaySample(byte huge *data,longword len)
{
asm pushf
asm cli
SDL_IndicatePC(true);
pcLengthLeft = len;
pcSound = (volatile byte far *)data;
asm popf
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCStopSample() - Stops a sample playing on the PC speaker
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_PCStopSample(void)
{
asm pushf
asm cli
(long)pcSound = 0;
SDL_IndicatePC(false);
asm in al,0x61 // Turn the speaker off
asm and al,0xfd // ~2
asm out 0x61,al
asm popf
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCPlaySound() - Plays the specified sound on the PC speaker
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_PCPlaySound(PCSound far *sound)
{
asm pushf
asm cli
pcLastSample = -1;
pcLengthLeft = sound->common.length;
pcSound = sound->data;
asm popf
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCStopSound() - Stops the current sound playing on the PC Speaker
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_PCStopSound(void)
{
asm pushf
asm cli
(long)pcSound = 0;
asm in al,0x61 // Turn the speaker off
asm and al,0xfd // ~2
asm out 0x61,al
asm popf
}
#if 0
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCService() - Handles playing the next sample in a PC sound
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_PCService(void)
{
byte s;
word t;
if (pcSound)
{
s = *pcSound++;
if (s != pcLastSample)
{
asm pushf
asm cli
pcLastSample = s;
if (s) // We have a frequency!
{
t = pcSoundLookup[s];
asm mov bx,[t]
asm mov al,0xb6 // Write to channel 2 (speaker) timer
asm out 43h,al
asm mov al,bl
asm out 42h,al // Low byte
asm mov al,bh
asm out 42h,al // High byte
asm in al,0x61 // Turn the speaker & gate on
asm or al,3
asm out 0x61,al
}
else // Time for some silence
{
asm in al,0x61 // Turn the speaker & gate off
asm and al,0xfc // ~3
asm out 0x61,al
}
asm popf
}
if (!(--pcLengthLeft))
{
SDL_PCStopSound();
SDL_SoundFinished();
}
}
}
#endif
///////////////////////////////////////////////////////////////////////////
//
// SDL_ShutPC() - Turns off the pc speaker
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_ShutPC(void)
{
asm pushf
asm cli
pcSound = 0;
asm in al,0x61 // Turn the speaker & gate off
asm and al,0xfc // ~3
asm out 0x61,al
asm popf
}
//
// Stuff for digitized sounds
//
memptr
SDL_LoadDigiSegment(word page)
{
memptr addr;
#if 0 // for debugging
asm mov dx,STATUS_REGISTER_1
asm in al,dx
asm mov dx,ATR_INDEX
asm mov al,ATR_OVERSCAN
asm out dx,al
asm mov al,10 // bright green
asm out dx,al
#endif
addr = PM_GetSoundPage(page);
PM_SetPageLock(PMSoundStart + page,pml_Locked);
#if 0 // for debugging
asm mov dx,STATUS_REGISTER_1
asm in al,dx
asm mov dx,ATR_INDEX
asm mov al,ATR_OVERSCAN
asm out dx,al
asm mov al,3 // blue
asm out dx,al
asm mov al,0x20 // normal
asm out dx,al
#endif
return(addr);
}
void
SDL_PlayDigiSegment(memptr addr,word len)
{
switch (DigiMode)
{
case sds_PC:
SDL_PCPlaySample(addr,len);
break;
case sds_SoundSource:
SDL_SSPlaySample(addr,len);
break;
case sds_SoundBlaster:
SDL_SBPlaySample(addr,len);
break;
}
}
void
SD_StopDigitized(void)
{
int i;
asm pushf
asm cli
DigiLeft = 0;
DigiNextAddr = nil;
DigiNextLen = 0;
DigiMissed = false;
DigiPlaying = false;
DigiNumber = DigiPriority = 0;
SoundPositioned = false;
if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))
SDL_SoundFinished();
switch (DigiMode)
{
case sds_PC:
SDL_PCStopSample();
break;
case sds_SoundSource:
SDL_SSStopSample();
break;
case sds_SoundBlaster:
SDL_SBStopSample();
break;
}
asm popf
for (i = DigiLastStart;i < DigiLastEnd;i++)
PM_SetPageLock(i + PMSoundStart,pml_Unlocked);
DigiLastStart = 1;
DigiLastEnd = 0;
}
void
SD_Poll(void)
{
if (DigiLeft && !DigiNextAddr)
{
DigiNextLen = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);
DigiLeft -= DigiNextLen;
if (!DigiLeft)
DigiLastSegment = true;
DigiNextAddr = SDL_LoadDigiSegment(DigiPage++);
}
if (DigiMissed && DigiNextAddr)
{
SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);
DigiNextAddr = nil;
DigiMissed = false;
if (DigiLastSegment)
{
DigiPlaying = false;
DigiLastSegment = false;
}
}
SDL_SetTimerSpeed();
}
void
SD_SetPosition(int leftpos,int rightpos)
{
if
(
(leftpos < 0)
|| (leftpos > 15)
|| (rightpos < 0)
|| (rightpos > 15)
|| ((leftpos == 15) && (rightpos == 15))
)
Quit("SD_SetPosition: Illegal position");
switch (DigiMode)
{
case sds_SoundBlaster:
SDL_PositionSBP(leftpos,rightpos);
break;
}
}
void
SD_PlayDigitized(word which,int leftpos,int rightpos)
{
word len;
memptr addr;
if (!DigiMode)
return;
SD_StopDigitized();
if (which >= NumDigi)
Quit("SD_PlayDigitized: bad sound number");
SD_SetPosition(leftpos,rightpos);
DigiPage = DigiList[(which * 2) + 0];
DigiLeft = DigiList[(which * 2) + 1];
DigiLastStart = DigiPage;
DigiLastEnd = DigiPage + ((DigiLeft + (PMPageSize - 1)) / PMPageSize);
len = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);
addr = SDL_LoadDigiSegment(DigiPage++);
DigiPlaying = true;
DigiLastSegment = false;
SDL_PlayDigiSegment(addr,len);
DigiLeft -= len;
if (!DigiLeft)
DigiLastSegment = true;
SD_Poll();
}
void
SDL_DigitizedDone(void)
{
if (DigiNextAddr)
{
SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);
DigiNextAddr = nil;
DigiMissed = false;
}
else
{
if (DigiLastSegment)
{
DigiPlaying = false;
DigiLastSegment = false;
if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))
{
SDL_SoundFinished();
}
else
DigiNumber = DigiPriority = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -