Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
W
wolf3d
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PocketInsanity
wolf3d
Commits
55edef7f
Commit
55edef7f
authored
Apr 19, 2000
by
Steven Fuller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More cleanups (id_vl.c)
parent
7d7c4678
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
119 additions
and
3779 deletions
+119
-3779
id_sd.c
src/id_sd.c
+72
-2041
id_sd.h
src/id_sd.h
+6
-14
id_sd_a.asm
src/id_sd_a.asm
+0
-526
id_vl.c
src/id_vl.c
+40
-427
id_vl.h
src/id_vl.h
+1
-1
id_vl_a.asm
src/id_vl_a.asm
+0
-742
wl_main.c
src/wl_main.c
+0
-16
wl_menu.c
src/wl_menu.c
+0
-12
No files found.
src/id_sd.c
View file @
55edef7f
...
@@ -2,26 +2,6 @@
...
@@ -2,26 +2,6 @@
#include "id_heads.h"
#include "id_heads.h"
#define SDL_SoundFinished() {SoundNumber = SoundPriority = 0;}
// Macros for SoundBlaster stuff
#define sbOut(n,b) outportb((n) + sbLocation,b)
#define sbIn(n) inportb((n) + sbLocation)
#define sbWriteDelay() while (sbIn(sbWriteStat) & 0x80);
#define sbReadDelay() while (sbIn(sbDataAvail) & 0x80);
// Macros for AdLib stuff
#define selreg(n) outportb(alFMAddr,n)
#define writereg(n) outportb(alFMData,n)
#define readstat() inportb(alFMStatus)
// Imports from ID_SD_A.ASM
extern
void
SDL_SetDS
(
void
),
SDL_IndicatePC
(
boolean
on
);
extern
void
interrupt
SDL_t0ExtremeAsmService
(
void
),
SDL_t0FastAsmService
(
void
),
SDL_t0SlowAsmService
(
void
);
// Global variables
// Global variables
boolean
SoundSourcePresent
,
boolean
SoundSourcePresent
,
AdLibPresent
,
AdLibPresent
,
...
@@ -54,7 +34,6 @@ static char *ParmStrings[] =
...
@@ -54,7 +34,6 @@ static char *ParmStrings[] =
"ss3"
,
"ss3"
,
nil
nil
};
};
static
void
(
*
SoundUserHook
)(
void
);
soundnames
SoundNumber
,
DigiNumber
;
soundnames
SoundNumber
,
DigiNumber
;
word
SoundPriority
,
DigiPriority
;
word
SoundPriority
,
DigiPriority
;
int
LeftPosition
,
RightPosition
;
int
LeftPosition
,
RightPosition
;
...
@@ -81,9 +60,8 @@ static byte sbDMA = 1,
...
@@ -81,9 +60,8 @@ static byte sbDMA = 1,
sba3Vals
[]
=
{
1
,
3
,
0
,
7
};
sba3Vals
[]
=
{
1
,
3
,
0
,
7
};
static
int
sbLocation
=
-
1
,
sbInterrupt
=
7
,
sbIntVec
=
0xf
,
static
int
sbLocation
=
-
1
,
sbInterrupt
=
7
,
sbIntVec
=
0xf
,
sbIntVectors
[]
=
{
-
1
,
-
1
,
0xa
,
0xb
,
-
1
,
0xd
,
-
1
,
0xf
,
-
1
,
-
1
,
-
1
};
sbIntVectors
[]
=
{
-
1
,
-
1
,
0xa
,
0xb
,
-
1
,
0xd
,
-
1
,
0xf
,
-
1
,
-
1
,
-
1
};
static
volatile
longword
sbNextSegLen
;
static
longword
sbNextSegLen
;
static
volatile
SampledSound
*
sbSamples
;
static
SampledSound
*
sbSamples
;
static
void
interrupt
(
*
sbOldIntHand
)(
void
);
static
byte
sbpOldFMMix
,
sbpOldVOCMix
;
static
byte
sbpOldFMMix
,
sbpOldVOCMix
;
// SoundSource variables
// SoundSource variables
...
@@ -91,8 +69,8 @@ static byte sbpOldFMMix,sbpOldVOCMix;
...
@@ -91,8 +69,8 @@ static byte sbpOldFMMix,sbpOldVOCMix;
boolean
ssActive
;
boolean
ssActive
;
word
ssControl
,
ssStatus
,
ssData
;
word
ssControl
,
ssStatus
,
ssData
;
byte
ssOn
,
ssOff
;
byte
ssOn
,
ssOff
;
volatile
byte
*
ssSample
;
byte
*
ssSample
;
volatile
longword
ssLengthLeft
;
longword
ssLengthLeft
;
// PC Sound variables
// PC Sound variables
volatile
byte
pcLastSample
,
*
pcSound
;
volatile
byte
pcLastSample
,
*
pcSound
;
...
@@ -126,2143 +104,196 @@ static word sqMode,sqFadeStep;
...
@@ -126,2143 +104,196 @@ static word sqMode,sqFadeStep;
// Internal routines
// Internal routines
void
SDL_DigitizedDone
(
void
);
void
SDL_DigitizedDone
(
void
);
///////////////////////////////////////////////////////////////////////////
void
SD_StopDigitized
(
void
)
//
// SDL_SetTimer0() - Sets system timer 0 to the specified speed
//
///////////////////////////////////////////////////////////////////////////
#pragma argsused
static
void
SDL_SetTimer0
(
word
speed
)
{
#ifndef TPROF // If using Borland's profiling, don't screw with the timer
asm
pushf
asm
cli
outportb
(
0x43
,
0x36
);
// Change timer 0
outportb
(
0x40
,
speed
);
outportb
(
0x40
,
speed
>>
8
);
// Kludge to handle special case for digitized PC sounds
if
(
TimerDivisor
==
(
1192030
/
(
TickBase
*
100
)))
TimerDivisor
=
(
1192030
/
(
TickBase
*
10
));
else
TimerDivisor
=
speed
;
asm
popf
#else
TimerDivisor
=
0x10000
;
#endif
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of
// interrupts generated by system timer 0 per second
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_SetIntsPerSec
(
word
ints
)
{
TimerRate
=
ints
;
SDL_SetTimer0
(
1192030
/
ints
);
}
static
void
SDL_SetTimerSpeed
(
void
)
{
{
word
rate
;
void
interrupt
(
*
isr
)(
void
);
if
((
DigiMode
==
sds_PC
)
&&
DigiPlaying
)
{
rate
=
TickBase
*
100
;
isr
=
SDL_t0ExtremeAsmService
;
}
else
if
(
(
MusicMode
==
smm_AdLib
)
||
((
DigiMode
==
sds_SoundSource
)
&&
DigiPlaying
)
)
{
rate
=
TickBase
*
10
;
isr
=
SDL_t0FastAsmService
;
}
else
{
rate
=
TickBase
*
2
;
isr
=
SDL_t0SlowAsmService
;
}
if
(
rate
!=
TimerRate
)
{
setvect
(
8
,
isr
);
SDL_SetIntsPerSec
(
rate
);
TimerRate
=
rate
;
}
}
}
//
void
SD_Poll
(
void
)
// SoundBlaster code
//
///////////////////////////////////////////////////////////////////////////
//
// SDL_SBStopSample() - Stops any active sampled sound and causes DMA
// requests from the SoundBlaster to cease
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_SBStopSample
(
void
)
{
{
byte
is
;
asm
pushf
asm
cli
if
(
sbSamplePlaying
)
{
sbSamplePlaying
=
false
;
sbWriteDelay
();
sbOut
(
sbWriteCmd
,
0xd0
);
// Turn off DSP DMA
is
=
inportb
(
0x21
);
// Restore interrupt mask bit
if
(
sbOldIntMask
&
(
1
<<
sbInterrupt
))
is
|=
(
1
<<
sbInterrupt
);
else
is
&=
~
(
1
<<
sbInterrupt
);
outportb
(
0x21
,
is
);
}
asm
popf
}
}
///////////////////////////////////////////////////////////////////////////
void
SD_SetPosition
(
int
leftpos
,
int
rightpos
)
//
// SDL_SBPlaySeg() - Plays a chunk of sampled sound on the SoundBlaster
// Insures that the chunk doesn't cross a bank boundary, programs the DMA
// controller, and tells the SB to start doing DMA requests for DAC
//
///////////////////////////////////////////////////////////////////////////
static
longword
SDL_SBPlaySeg
(
volatile
byte
*
data
,
longword
length
)
{
{
unsigned
datapage
;
longword
dataofs
,
uselen
;
uselen
=
length
;
datapage
=
FP_SEG
(
data
)
>>
12
;
dataofs
=
((
FP_SEG
(
data
)
&
0xfff
)
<<
4
)
+
FP_OFF
(
data
);
if
(
dataofs
>=
0x10000
)
{
datapage
++
;
dataofs
-=
0x10000
;
}
if
(
dataofs
+
uselen
>
0x10000
)
uselen
=
0x10000
-
dataofs
;
uselen
--
;
// Program the DMA controller
asm
pushf
asm
cli
outportb
(
0x0a
,
sbDMA
|
4
);
// Mask off DMA on channel sbDMA
outportb
(
0x0c
,
0
);
// Clear byte ptr flip-flop to lower byte
outportb
(
0x0b
,
0x49
);
// Set transfer mode for D/A conv
outportb
(
sbDMAa2
,(
byte
)
dataofs
);
// Give LSB of address
outportb
(
sbDMAa2
,(
byte
)(
dataofs
>>
8
));
// Give MSB of address
outportb
(
sbDMAa1
,(
byte
)
datapage
);
// Give page of address
outportb
(
sbDMAa3
,(
byte
)
uselen
);
// Give LSB of length
outportb
(
sbDMAa3
,(
byte
)(
uselen
>>
8
));
// Give MSB of length
outportb
(
0x0a
,
sbDMA
);
// Re-enable DMA on channel sbDMA
// Start playing the thing
sbWriteDelay
();
sbOut
(
sbWriteCmd
,
0x14
);
sbWriteDelay
();
sbOut
(
sbWriteData
,(
byte
)
uselen
);
sbWriteDelay
();
sbOut
(
sbWriteData
,(
byte
)(
uselen
>>
8
));
asm
popf
return
(
uselen
+
1
);
}
}
///////////////////////////////////////////////////////////////////////////
void
SD_PlayDigitized
(
word
which
,
int
leftpos
,
int
rightpos
)
//
// SDL_SBService() - Services the SoundBlaster DMA interrupt
//
///////////////////////////////////////////////////////////////////////////
static
void
interrupt
SDL_SBService
(
void
)
{
{
longword
used
;
sbIn
(
sbDataAvail
);
// Ack interrupt to SB
if
(
sbNextSegPtr
)
{
used
=
SDL_SBPlaySeg
(
sbNextSegPtr
,
sbNextSegLen
);
if
(
sbNextSegLen
<=
used
)
sbNextSegPtr
=
nil
;
else
{
sbNextSegPtr
+=
used
;
sbNextSegLen
-=
used
;
}
}
else
{
SDL_SBStopSample
();
SDL_DigitizedDone
();
}
outportb
(
0x20
,
0x20
);
// Ack interrupt
}
}
///////////////////////////////////////////////////////////////////////////
void
SDL_DigitizedDone
(
void
)
//
// SDL_SBPlaySample() - Plays a sampled sound on the SoundBlaster. Sets up
// DMA to play the sound
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_SBPlaySample
(
byte
*
data
,
longword
len
)
{
{
longword
used
;
SDL_SBStopSample
();
asm
pushf
asm
cli
used
=
SDL_SBPlaySeg
(
data
,
len
);
if
(
len
<=
used
)
sbNextSegPtr
=
nil
;
else
{
sbNextSegPtr
=
data
+
used
;
sbNextSegLen
=
len
-
used
;
}
// Save old interrupt status and unmask ours
sbOldIntMask
=
inportb
(
0x21
);
outportb
(
0x21
,
sbOldIntMask
&
~
(
1
<<
sbInterrupt
));
sbWriteDelay
();
sbOut
(
sbWriteCmd
,
0xd4
);
// Make sure DSP DMA is enabled
sbSamplePlaying
=
true
;
asm
popf
}
}
///////////////////////////////////////////////////////////////////////////
void
SD_SetDigiDevice
(
SDSMode
mode
)
//
// SDL_PositionSBP() - Sets the attenuation levels for the left and right
// channels by using the mixer chip on the SB Pro. This hits a hole in
// the address map for normal SBs.
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_PositionSBP
(
int
leftpos
,
int
rightpos
)
{
{
byte
v
;
if
(
!
SBProPresent
)
return
;
leftpos
=
15
-
leftpos
;
rightpos
=
15
-
rightpos
;
v
=
((
leftpos
&
0x0f
)
<<
4
)
|
(
rightpos
&
0x0f
);
asm
pushf
asm
cli
sbOut
(
sbpMixerAddr
,
sbpmVoiceVol
);
sbOut
(
sbpMixerData
,
v
);
asm
popf
}
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_CheckSB() - Checks to see if a SoundBlaster resides at a
// particular I/O location
//
///////////////////////////////////////////////////////////////////////////
static
boolean
SDL_CheckSB
(
int
port
)
{
int
i
;
sbLocation
=
port
<<
4
;
// Initialize stuff for later use
sbOut
(
sbReset
,
true
);
// Reset the SoundBlaster DSP
asm
mov
dx
,
0x388
// Wait >4usec
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
sbOut
(
sbReset
,
false
);
// Turn off sb DSP reset
asm
mov
dx
,
0x388
// Wait >100usec
asm
mov
cx
,
100
usecloop:
asm
in
al
,
dx
asm
loop
usecloop
for
(
i
=
0
;
i
<
100
;
i
++
)
// Public routines
{
if
(
sbIn
(
sbDataAvail
)
&
0x80
)
// If data is available...
{
if
(
sbIn
(
sbReadData
)
==
0xaa
)
// If it matches correct value
return
(
true
);
else
{
sbLocation
=
-
1
;
// Otherwise not a SoundBlaster
return
(
false
);
}
}
}
sbLocation
=
-
1
;
// Retry count exceeded - fail
return
(
false
);
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// Checks to see if a SoundBlaster is in the system. If the port passed is
// SD_SetSoundMode() - Sets which sound hardware to use for sound effects
// -1, then it scans through all possible I/O locations. If the port
// passed is 0, then it uses the default (2). If the port is >0, then
// it just passes it directly to SDL_CheckSB()
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
boolean
boolean
SD_SetSoundMode
(
SDMode
mode
)
SDL_DetectSoundBlaster
(
int
port
)
{
{
int
i
;
return
false
;
if
(
port
==
0
)
// If user specifies default, use 2
port
=
2
;
if
(
port
==
-
1
)
{
if
(
SDL_CheckSB
(
2
))
// Check default before scanning
return
(
true
);
if
(
SDL_CheckSB
(
4
))
// Check other SB Pro location before scan
return
(
true
);
for
(
i
=
1
;
i
<=
6
;
i
++
)
// Scan through possible SB locations
{
if
((
i
==
2
)
||
(
i
==
4
))
continue
;
if
(
SDL_CheckSB
(
i
))
// If found at this address,
return
(
true
);
// return success
}
return
(
false
);
// All addresses failed, return failure
}
else
return
(
SDL_CheckSB
(
port
));
// User specified address or default
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SDL_SBSetDMA() - Sets the DMA channel to be used by the SoundBlaster
// SD_SetMusicMode() - sets the device to use for background music
// code. Sets up sbDMA, and sbDMAa1-sbDMAa3 (used by SDL_SBPlaySeg()).
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void
boolean
SD_SetMusicMode
(
SMMode
mode
)
SDL_SBSetDMA
(
byte
channel
)
{
{
if
(
channel
>
3
)
return
false
;
Quit
(
"SDL_SBSetDMA() - invalid SoundBlaster DMA channel"
);
sbDMA
=
channel
;
sbDMAa1
=
sba1Vals
[
channel
];
sbDMAa2
=
sba2Vals
[
channel
];
sbDMAa3
=
sba3Vals
[
channel
];
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SDL_StartSB() - Turns on the SoundBlaster
// SD_Startup() - starts up the Sound Mgr
// Detects all additional sound hardware and installs my ISR
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
void
SD_Startup
(
void
)
SDL_StartSB
(
void
)
{
{
byte
timevalue
,
test
;
if
(
SD_Started
)
sbIntVec
=
sbIntVectors
[
sbInterrupt
];
if
(
sbIntVec
<
0
)
Quit
(
"SDL_StartSB: Illegal or unsupported interrupt number for SoundBlaster"
);
sbOldIntHand
=
getvect
(
sbIntVec
);
// Get old interrupt handler
setvect
(
sbIntVec
,
SDL_SBService
);
// Set mine
sbWriteDelay
();
sbOut
(
sbWriteCmd
,
0xd1
);
// Turn on DSP speaker
// Set the SoundBlaster DAC time constant for 7KHz
timevalue
=
256
-
(
1000000
/
7000
);
sbWriteDelay
();
sbOut
(
sbWriteCmd
,
0x40
);
sbWriteDelay
();
sbOut
(
sbWriteData
,
timevalue
);
SBProPresent
=
false
;
if
(
sbNoProCheck
)
return
;
return
;
// Check to see if this is a SB Pro
SD_Started
=
true
;
sbOut
(
sbpMixerAddr
,
sbpmFMVol
);
sbpOldFMMix
=
sbIn
(
sbpMixerData
);
sbOut
(
sbpMixerData
,
0xbb
);
test
=
sbIn
(
sbpMixerData
);
if
(
test
==
0xbb
)
{
// Boost FM output levels to be equivilent with digitized output
sbOut
(
sbpMixerData
,
0xff
);
test
=
sbIn
(
sbpMixerData
);
if
(
test
==
0xff
)
{
SBProPresent
=
true
;
// Save old Voice output levels (SB Pro)
sbOut
(
sbpMixerAddr
,
sbpmVoiceVol
);
sbpOldVOCMix
=
sbIn
(
sbpMixerData
);
// Turn SB Pro stereo DAC off
sbOut
(
sbpMixerAddr
,
sbpmControl
);
sbOut
(
sbpMixerData
,
0
);
// 0=off,2=on
}
}
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SDL_ShutSB() - Turns off the SoundBlaster
// SD_Shutdown() - shuts down the Sound Mgr
// Removes sound ISR and turns off whatever sound hardware was active
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
void
SD_Shutdown
(
void
)
SDL_ShutSB
(
void
)
{
{
SDL_SBStopSample
();
if
(
!
SD_Started
)
return
;
if
(
SBProPresent
)
{
// Restore FM output levels (SB Pro)
sbOut
(
sbpMixerAddr
,
sbpmFMVol
);
sbOut
(
sbpMixerData
,
sbpOldFMMix
);
// Restore Voice output levels (SB Pro)
SD_MusicOff
();
sbOut
(
sbpMixerAddr
,
sbpmVoiceVol
);
SD_StopSound
();
sbOut
(
sbpMixerData
,
sbpOldVOCMix
);
}
setvect
(
sbIntVec
,
sbOldIntHand
);
// Set vector back
SD_Started
=
false
;
}
}
// Sound Source Code
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SDL_SSStopSample() - Stops a sample playing on the Sound Source
// SD_PositionSound() - Sets up a stereo imaging location for the next
// sound to be played. Each channel ranges from 0 to 15.
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
SDL_SSStopSample
(
void
)
void
SD_PositionSound
(
int
leftvol
,
int
rightvol
)
{
{
asm
pushf
LeftPosition
=
leftvol
;
asm
cli
RightPosition
=
rightvol
;
nextsoundpos
=
true
;
(
long
)
ssSample
=
0
;
asm
popf
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SD
L_SSService() - Handles playing the next sample on the Sound Sourc
e
// SD
_PlaySound() - plays the specified sound on the appropriate hardwar
e
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
boolean
SD_PlaySound
(
soundnames
sound
)
SDL_SSService
(
void
)
{
{
boolean
gotit
;
boolean
ispos
;
byte
v
;
int
lp
,
rp
;
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:
;
}
///////////////////////////////////////////////////////////////////////////
lp
=
LeftPosition
;
//
rp
=
RightPosition
;
// SDL_SSPlaySample() - Plays the specified sample on the Sound Source
LeftPosition
=
0
;
//
RightPosition
=
0
;
///////////////////////////////////////////////////////////////////////////
static
void
SDL_SSPlaySample
(
byte
*
data
,
longword
len
)
{
asm
pushf
asm
cli
ssLengthLeft
=
len
;
ispos
=
nextsoundpos
;
ssSample
=
(
volatile
byte
*
)
data
;
nextsoundpos
=
false
;
asm
popf
return
false
;
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SDL_StartSS() - Sets up for and turns on the Sound Source
// SD_SoundPlaying() - returns the sound number that's playing, or 0 if
// no sound is playing
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
word
SD_SoundPlaying
(
void
)
SDL_StartSS
(
void
)
{
{
if
(
ssPort
==
3
)
return
false
;
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
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SD
L_ShutSS() - Turns off the Sound Source
// SD
_StopSound() - if a sound is playing, stops it
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
void
SD_StopSound
(
void
)
SDL_ShutSS
(
void
)
{
{
outportb
(
ssControl
,
ssOff
);
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SDL_CheckSS() - Checks to see if a Sound Source is present at the
// SD_WaitSoundDone() - waits until the current sound is done playing
// location specified by the sound source variables
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
boolean
void
SD_WaitSoundDone
(
void
)
SDL_CheckSS
(
void
)
{
{
boolean
present
=
false
;
while
(
SD_SoundPlaying
())
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
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_PCPlaySample
(
byte
*
data
,
longword
len
)
{
asm
pushf
asm
cli
SDL_IndicatePC
(
true
);
pcLengthLeft
=
len
;
pcSound
=
(
volatile
byte
*
)
data
;
asm
popf
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SD
L_PCStopSample() - Stops a sample playing on the PC speak
er
// SD
_MusicOn() - turns on the sequenc
er
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
SDL_PCStopSample
(
void
)
void
SD_MusicOn
(
void
)
{
{
asm
pushf
sqActive
=
true
;
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
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SD
L_PCPlaySound() - Plays the specified sound on the PC speaker
// SD
_MusicOff() - turns off the sequencer and any playing notes
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
SDL_PCPlaySound
(
PCSound
*
soun
d
)
void
SD_MusicOff
(
voi
d
)
{
{
asm
pushf
sqActive
=
false
;
asm
cli
pcLastSample
=
-
1
;
pcLengthLeft
=
sound
->
common
.
length
;
pcSound
=
sound
->
data
;
asm
popf
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// SD
L_PCStopSound() - Stops the current sound playing on the PC Speaker
// SD
_StartMusic() - starts playing the music pointed to
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
SDL_PCStopSound
(
void
)
void
SD_StartMusic
(
MusicGroup
*
music
)
{
{
asm
pushf
SD_MusicOff
();
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
// SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()
// to see if the fadeout is complete
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static void
void
SD_FadeOutMusic
(
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
// SD_MusicPlaying() - returns true if music is currently playing, false if
// not
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static
void
boolean
SD_MusicPlaying
(
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
)
return
false
;
{
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
;
SoundPositioned
=
false
;
}
else
DigiMissed
=
true
;
}
}
void
SD_SetDigiDevice
(
SDSMode
mode
)
{
boolean
devicenotpresent
;
if
(
mode
==
DigiMode
)
return
;
SD_StopDigitized
();
devicenotpresent
=
false
;
switch
(
mode
)
{
case
sds_SoundBlaster
:
if
(
!
SoundBlasterPresent
)
{
if
(
SoundSourcePresent
)
mode
=
sds_SoundSource
;
else
devicenotpresent
=
true
;
}
break
;
case
sds_SoundSource
:
if
(
!
SoundSourcePresent
)
devicenotpresent
=
true
;
break
;
}
if
(
!
devicenotpresent
)
{
if
(
DigiMode
==
sds_SoundSource
)
SDL_ShutSS
();
DigiMode
=
mode
;
if
(
mode
==
sds_SoundSource
)
SDL_StartSS
();
SDL_SetTimerSpeed
();
}
}
void
SDL_SetupDigi
(
void
)
{
memptr
list
;
word
*
p
,
pg
;
int
i
;
PM_UnlockMainMem
();
MM_GetPtr
(
&
list
,
PMPageSize
);
PM_CheckMainMem
();
p
=
(
word
*
)
MK_FP
(
PM_GetPage
(
ChunksInFile
-
1
),
0
);
_fmemcpy
((
void
*
)
list
,(
void
*
)
p
,
PMPageSize
);
pg
=
PMSoundStart
;
for
(
i
=
0
;
i
<
PMPageSize
/
(
sizeof
(
word
)
*
2
);
i
++
,
p
+=
2
)
{
if
(
pg
>=
ChunksInFile
-
1
)
break
;
pg
+=
(
p
[
1
]
+
(
PMPageSize
-
1
))
/
PMPageSize
;
}
PM_UnlockMainMem
();
MM_GetPtr
((
memptr
*
)
&
DigiList
,
i
*
sizeof
(
word
)
*
2
);
_fmemcpy
((
void
*
)
DigiList
,(
void
*
)
list
,
i
*
sizeof
(
word
)
*
2
);
MM_FreePtr
(
&
list
);
NumDigi
=
i
;
for
(
i
=
0
;
i
<
LASTSOUND
;
i
++
)
DigiMap
[
i
]
=
-
1
;
}
// AdLib Code
///////////////////////////////////////////////////////////////////////////
//
// alOut(n,b) - Puts b in AdLib card register n
//
///////////////////////////////////////////////////////////////////////////
void
alOut
(
byte
n
,
byte
b
)
{
asm
pushf
asm
cli
asm
mov
dx
,
0x388
asm
mov
al
,[
n
]
asm
out
dx
,
al
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
inc
dx
asm
mov
al
,[
b
]
asm
out
dx
,
al
asm
popf
asm
dec
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
asm
in
al
,
dx
}
#if 0
///////////////////////////////////////////////////////////////////////////
//
// SDL_SetInstrument() - Puts an instrument into a generator
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_SetInstrument(int track,int which,Instrument *inst,boolean percussive)
{
byte c,m;
if (percussive)
{
c = pcarriers[which];
m = pmodifiers[which];
}
else
{
c = carriers[which];
m = modifiers[which];
}
tracks[track - 1]->inst = *inst;
tracks[track - 1]->percussive = percussive;
alOut(m + alChar,inst->mChar);
alOut(m + alScale,inst->mScale);
alOut(m + alAttack,inst->mAttack);
alOut(m + alSus,inst->mSus);
alOut(m + alWave,inst->mWave);
// Most percussive instruments only use one cell
if (c != 0xff)
{
alOut(c + alChar,inst->cChar);
alOut(c + alScale,inst->cScale);
alOut(c + alAttack,inst->cAttack);
alOut(c + alSus,inst->cSus);
alOut(c + alWave,inst->cWave);
}
alOut(which + alFeedCon,inst->nConn); // DEBUG - I think this is right
}
#endif
///////////////////////////////////////////////////////////////////////////
//
// SDL_ALStopSound() - Turns off any sound effects playing through the
// AdLib card
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_ALStopSound
(
void
)
{
asm
pushf
asm
cli
(
long
)
alSound
=
0
;
alOut
(
alFreqH
+
0
,
0
);
asm
popf
}
static
void
SDL_AlSetFXInst
(
Instrument
*
inst
)
{
byte
c
,
m
;
m
=
modifiers
[
0
];
c
=
carriers
[
0
];
alOut
(
m
+
alChar
,
inst
->
mChar
);
alOut
(
m
+
alScale
,
inst
->
mScale
);
alOut
(
m
+
alAttack
,
inst
->
mAttack
);
alOut
(
m
+
alSus
,
inst
->
mSus
);
alOut
(
m
+
alWave
,
inst
->
mWave
);
alOut
(
c
+
alChar
,
inst
->
cChar
);
alOut
(
c
+
alScale
,
inst
->
cScale
);
alOut
(
c
+
alAttack
,
inst
->
cAttack
);
alOut
(
c
+
alSus
,
inst
->
cSus
);
alOut
(
c
+
alWave
,
inst
->
cWave
);
// Note: Switch commenting on these lines for old MUSE compatibility
// alOut(alFeedCon,inst->nConn);
alOut
(
alFeedCon
,
0
);
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_ALPlaySound() - Plays the specified sound on the AdLib card
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_ALPlaySound
(
AdLibSound
*
sound
)
{
Instrument
*
inst
;
byte
*
data
;
SDL_ALStopSound
();
asm
pushf
asm
cli
alLengthLeft
=
sound
->
common
.
length
;
data
=
sound
->
data
;
data
++
;
data
--
;
alSound
=
(
byte
*
)
data
;
alBlock
=
((
sound
->
block
&
7
)
<<
2
)
|
0x20
;
inst
=
&
sound
->
inst
;
if
(
!
(
inst
->
mSus
|
inst
->
cSus
))
{
asm
popf
Quit
(
"SDL_ALPlaySound() - Bad instrument"
);
}
SDL_AlSetFXInst
(
&
alZeroInst
);
// DEBUG
SDL_AlSetFXInst
(
inst
);
asm
popf
}
#if 0
///////////////////////////////////////////////////////////////////////////
//
// SDL_ALSoundService() - Plays the next sample out through the AdLib card
//
///////////////////////////////////////////////////////////////////////////
//static void
void
SDL_ALSoundService(void)
{
byte s;
if (alSound)
{
s = *alSound++;
if (!s)
alOut(alFreqH + 0,0);
else
{
alOut(alFreqL + 0,s);
alOut(alFreqH + 0,alBlock);
}
if (!(--alLengthLeft))
{
(long)alSound = 0;
alOut(alFreqH + 0,0);
SDL_SoundFinished();
}
}
}
#endif
#if 0
void
SDL_ALService(void)
{
byte a,v;
word w;
if (!sqActive)
return;
while (sqHackLen && (sqHackTime <= alTimeCount))
{
w = *sqHackPtr++;
sqHackTime = alTimeCount + *sqHackPtr++;
asm mov dx,[w]
asm mov [a],dl
asm mov [v],dh
alOut(a,v);
sqHackLen -= 4;
}
alTimeCount++;
if (!sqHackLen)
{
sqHackPtr = (word *)sqHack;
sqHackLen = sqHackSeqLen;
alTimeCount = sqHackTime = 0;
}
}
#endif
///////////////////////////////////////////////////////////////////////////
//
// SDL_ShutAL() - Shuts down the AdLib card for sound effects
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_ShutAL
(
void
)
{
asm
pushf
asm
cli
alOut
(
alEffects
,
0
);
alOut
(
alFreqH
+
0
,
0
);
SDL_AlSetFXInst
(
&
alZeroInst
);
alSound
=
0
;
asm
popf
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_CleanAL() - Totally shuts down the AdLib card
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_CleanAL
(
void
)
{
int
i
;
asm
pushf
asm
cli
alOut
(
alEffects
,
0
);
for
(
i
=
1
;
i
<
0xf5
;
i
++
)
alOut
(
i
,
0
);
asm
popf
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_StartAL() - Starts up the AdLib card for sound effects
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_StartAL
(
void
)
{
alFXReg
=
0
;
alOut
(
alEffects
,
alFXReg
);
SDL_AlSetFXInst
(
&
alZeroInst
);
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster
// emulating an AdLib) present
//
///////////////////////////////////////////////////////////////////////////
static
boolean
SDL_DetectAdLib
(
void
)
{
byte
status1
,
status2
;
int
i
;
alOut
(
4
,
0x60
);
// Reset T1 & T2
alOut
(
4
,
0x80
);
// Reset IRQ
status1
=
readstat
();
alOut
(
2
,
0xff
);
// Set timer 1
alOut
(
4
,
0x21
);
// Start timer 1
#if 0
SDL_Delay(TimerDelay100);
#else
asm
mov
dx
,
0x388
asm
mov
cx
,
100
usecloop:
asm
in
al
,
dx
asm
loop
usecloop
#endif
status2
=
readstat
();
alOut
(
4
,
0x60
);
alOut
(
4
,
0x80
);
if
(((
status1
&
0xe0
)
==
0x00
)
&&
((
status2
&
0xe0
)
==
0xc0
))
{
for
(
i
=
1
;
i
<=
0xf5
;
i
++
)
// Zero all the registers
alOut
(
i
,
0
);
alOut
(
1
,
0x20
);
// Set WSE=1
alOut
(
8
,
0
);
// Set CSM=0 & SEL=0
return
(
true
);
}
else
return
(
false
);
}
#if 0
///////////////////////////////////////////////////////////////////////////
//
// SDL_t0Service() - My timer 0 ISR which handles the different timings and
// dispatches to whatever other routines are appropriate
//
///////////////////////////////////////////////////////////////////////////
static void interrupt
SDL_t0Service(void)
{
static word count = 1;
#if 1 // 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,4 // red
asm out dx,al
#endif
HackCount++;
if ((MusicMode == smm_AdLib) || (DigiMode == sds_SoundSource))
{
SDL_ALService();
SDL_SSService();
// if (!(++count & 7))
if (!(++count % 10))
{
LocalTime++;
TimeCount++;
if (SoundUserHook)
SoundUserHook();
}
// if (!(count & 3))
if (!(count % 5))
{
switch (SoundMode)
{
case sdm_PC:
SDL_PCService();
break;
case sdm_AdLib:
SDL_ALSoundService();
break;
}
}
}
else
{
if (!(++count & 1))
{
LocalTime++;
TimeCount++;
if (SoundUserHook)
SoundUserHook();
}
switch (SoundMode)
{
case sdm_PC:
SDL_PCService();
break;
case sdm_AdLib:
SDL_ALSoundService();
break;
}
}
asm mov ax,[WORD PTR TimerCount]
asm add ax,[WORD PTR TimerDivisor]
asm mov [WORD PTR TimerCount],ax
asm jnc myack
t0OldService(); // If we overflow a word, time to call old int handler
asm jmp olddone
myack:;
outportb(0x20,0x20); // Ack the interrupt
olddone:;
#if 1 // 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
}
#endif
////////////////////////////////////////////////////////////////////////////
//
// SDL_ShutDevice() - turns off whatever device was being used for sound fx
//
////////////////////////////////////////////////////////////////////////////
static
void
SDL_ShutDevice
(
void
)
{
switch
(
SoundMode
)
{
case
sdm_PC
:
SDL_ShutPC
();
break
;
case
sdm_AdLib
:
SDL_ShutAL
();
break
;
}
SoundMode
=
sdm_Off
;
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_CleanDevice() - totally shuts down all sound devices
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_CleanDevice
(
void
)
{
if
((
SoundMode
==
sdm_AdLib
)
||
(
MusicMode
==
smm_AdLib
))
SDL_CleanAL
();
}
///////////////////////////////////////////////////////////////////////////
//
// SDL_StartDevice() - turns on whatever device is to be used for sound fx
//
///////////////////////////////////////////////////////////////////////////
static
void
SDL_StartDevice
(
void
)
{
switch
(
SoundMode
)
{
case
sdm_AdLib
:
SDL_StartAL
();
break
;
}
SoundNumber
=
SoundPriority
=
0
;
}
// Public routines
///////////////////////////////////////////////////////////////////////////
//
// SD_SetSoundMode() - Sets which sound hardware to use for sound effects
//
///////////////////////////////////////////////////////////////////////////
boolean
SD_SetSoundMode
(
SDMode
mode
)
{
boolean
result
=
false
;
word
tableoffset
;
SD_StopSound
();
if
((
mode
==
sdm_AdLib
)
&&
!
AdLibPresent
)
mode
=
sdm_PC
;
switch
(
mode
)
{
case
sdm_Off
:
NeedsDigitized
=
false
;
result
=
true
;
break
;
case
sdm_PC
:
tableoffset
=
STARTPCSOUNDS
;
NeedsDigitized
=
false
;
result
=
true
;
break
;
case
sdm_AdLib
:
if
(
AdLibPresent
)
{
tableoffset
=
STARTADLIBSOUNDS
;
NeedsDigitized
=
false
;
result
=
true
;
}
break
;
}
if
(
result
&&
(
mode
!=
SoundMode
))
{
SDL_ShutDevice
();
SoundMode
=
mode
;
SoundTable
=
(
word
*
)(
&
audiosegs
[
tableoffset
]);
SDL_StartDevice
();
}
SDL_SetTimerSpeed
();
return
(
result
);
}
///////////////////////////////////////////////////////////////////////////
//
// SD_SetMusicMode() - sets the device to use for background music
//
///////////////////////////////////////////////////////////////////////////
boolean
SD_SetMusicMode
(
SMMode
mode
)
{
boolean
result
=
false
;
SD_FadeOutMusic
();
while
(
SD_MusicPlaying
())
;
switch
(
mode
)
{
case
smm_Off
:
NeedsMusic
=
false
;
result
=
true
;
break
;
case
smm_AdLib
:
if
(
AdLibPresent
)
{
NeedsMusic
=
true
;
result
=
true
;
}
break
;
}
if
(
result
)
MusicMode
=
mode
;
SDL_SetTimerSpeed
();
return
(
result
);
}
///////////////////////////////////////////////////////////////////////////
//
// SD_Startup() - starts up the Sound Mgr
// Detects all additional sound hardware and installs my ISR
//
///////////////////////////////////////////////////////////////////////////
void
SD_Startup
(
void
)
{
int
i
;
if
(
SD_Started
)
return
;
SDL_SetDS
();
ssIsTandy
=
false
;
ssNoCheck
=
false
;
alNoCheck
=
false
;
sbNoCheck
=
false
;
sbNoProCheck
=
false
;
for
(
i
=
1
;
i
<
_argc
;
i
++
)
{
switch
(
US_CheckParm
(
_argv
[
i
],
ParmStrings
))
{
case
0
:
// No AdLib detection
alNoCheck
=
true
;
break
;
case
1
:
// No SoundBlaster detection
sbNoCheck
=
true
;
break
;
case
2
:
// No SoundBlaster Pro detection
sbNoProCheck
=
true
;
break
;
case
3
:
ssNoCheck
=
true
;
// No Sound Source detection
break
;
case
4
:
// Tandy Sound Source handling
ssIsTandy
=
true
;
break
;
case
5
:
// Sound Source present at LPT1
ssPort
=
1
;
ssNoCheck
=
SoundSourcePresent
=
true
;
break
;
case
6
:
// Sound Source present at LPT2
ssPort
=
2
;
ssNoCheck
=
SoundSourcePresent
=
true
;
break
;
case
7
:
// Sound Source present at LPT3
ssPort
=
3
;
ssNoCheck
=
SoundSourcePresent
=
true
;
break
;
}
}
SoundUserHook
=
0
;
t0OldService
=
getvect
(
8
);
// Get old timer 0 ISR
LocalTime
=
TimeCount
=
alTimeCount
=
0
;
SD_SetSoundMode
(
sdm_Off
);
SD_SetMusicMode
(
smm_Off
);
if
(
!
ssNoCheck
)
SoundSourcePresent
=
SDL_DetectSoundSource
();
if
(
!
alNoCheck
)
{
AdLibPresent
=
SDL_DetectAdLib
();
if
(
AdLibPresent
&&
!
sbNoCheck
)
{
int
port
=
-
1
;
char
*
env
=
getenv
(
"BLASTER"
);
if
(
env
)
{
long
temp
;
while
(
*
env
)
{
while
(
isspace
(
*
env
))
env
++
;
switch
(
toupper
(
*
env
))
{
case
'A'
:
temp
=
strtol
(
env
+
1
,
&
env
,
16
);
if
(
(
temp
>=
0x210
)
&&
(
temp
<=
0x260
)
&&
(
!
(
temp
&
0x00f
))
)
port
=
(
temp
-
0x200
)
>>
4
;
else
Quit
(
"SD_Startup: Unsupported address value in BLASTER"
);
break
;
case
'I'
:
temp
=
strtol
(
env
+
1
,
&
env
,
10
);
if
(
(
temp
>=
0
)
&&
(
temp
<=
10
)
&&
(
sbIntVectors
[
temp
]
!=
-
1
)
)
{
sbInterrupt
=
temp
;
sbIntVec
=
sbIntVectors
[
sbInterrupt
];
}
else
Quit
(
"SD_Startup: Unsupported interrupt value in BLASTER"
);
break
;
case
'D'
:
temp
=
strtol
(
env
+
1
,
&
env
,
10
);
if
((
temp
==
0
)
||
(
temp
==
1
)
||
(
temp
==
3
))
SDL_SBSetDMA
(
temp
);
else
Quit
(
"SD_Startup: Unsupported DMA value in BLASTER"
);
break
;
default:
while
(
isspace
(
*
env
))
env
++
;
while
(
*
env
&&
!
isspace
(
*
env
))
env
++
;
break
;
}
}
}
SoundBlasterPresent
=
SDL_DetectSoundBlaster
(
port
);
}
}
for
(
i
=
0
;
i
<
255
;
i
++
)
pcSoundLookup
[
i
]
=
i
*
60
;
if
(
SoundBlasterPresent
)
SDL_StartSB
();
SDL_SetupDigi
();
SD_Started
=
true
;
}
///////////////////////////////////////////////////////////////////////////
//
// SD_Default() - Sets up the default behaviour for the Sound Mgr whether
// the config file was present or not.
//
///////////////////////////////////////////////////////////////////////////
void
SD_Default
(
boolean
gotit
,
SDMode
sd
,
SMMode
sm
)
{
boolean
gotsd
,
gotsm
;
gotsd
=
gotsm
=
gotit
;
if
(
gotsd
)
// Make sure requested sound hardware is available
{
switch
(
sd
)
{
case
sdm_AdLib
:
gotsd
=
AdLibPresent
;
break
;
}
}
if
(
!
gotsd
)
{
if
(
AdLibPresent
)
sd
=
sdm_AdLib
;
else
sd
=
sdm_PC
;
}
if
(
sd
!=
SoundMode
)
SD_SetSoundMode
(
sd
);
if
(
gotsm
)
// Make sure requested music hardware is available
{
switch
(
sm
)
{
case
sdm_AdLib
:
gotsm
=
AdLibPresent
;
break
;
}
}
if
(
!
gotsm
)
{
if
(
AdLibPresent
)
sm
=
smm_AdLib
;
}
if
(
sm
!=
MusicMode
)
SD_SetMusicMode
(
sm
);
}
///////////////////////////////////////////////////////////////////////////
//
// SD_Shutdown() - shuts down the Sound Mgr
// Removes sound ISR and turns off whatever sound hardware was active
//
///////////////////////////////////////////////////////////////////////////
void
SD_Shutdown
(
void
)
{
if
(
!
SD_Started
)
return
;
SD_MusicOff
();
SD_StopSound
();
SDL_ShutDevice
();
SDL_CleanDevice
();
if
(
SoundBlasterPresent
)
SDL_ShutSB
();
if
(
SoundSourcePresent
)
SDL_ShutSS
();
asm
pushf
asm
cli
SDL_SetTimer0
(
0
);
setvect
(
8
,
t0OldService
);
asm
popf
SD_Started
=
false
;
}
///////////////////////////////////////////////////////////////////////////
//
// SD_SetUserHook() - sets the routine that the Sound Mgr calls every 1/70th
// of a second from its timer 0 ISR
//
///////////////////////////////////////////////////////////////////////////
void
SD_SetUserHook
(
void
(
*
hook
)(
void
))
{
SoundUserHook
=
hook
;
}
///////////////////////////////////////////////////////////////////////////
//
// SD_PositionSound() - Sets up a stereo imaging location for the next
// sound to be played. Each channel ranges from 0 to 15.
//
///////////////////////////////////////////////////////////////////////////
void
SD_PositionSound
(
int
leftvol
,
int
rightvol
)
{
LeftPosition
=
leftvol
;
RightPosition
=
rightvol
;
nextsoundpos
=
true
;
}
///////////////////////////////////////////////////////////////////////////
//
// SD_PlaySound() - plays the specified sound on the appropriate hardware
//
///////////////////////////////////////////////////////////////////////////
boolean
SD_PlaySound
(
soundnames
sound
)
{
boolean
ispos
;
SoundCommon
*
s
;
int
lp
,
rp
;
lp
=
LeftPosition
;
rp
=
RightPosition
;
LeftPosition
=
0
;
RightPosition
=
0
;
ispos
=
nextsoundpos
;
nextsoundpos
=
false
;
if
(
sound
==
-
1
)
return
(
false
);
s
=
MK_FP
(
SoundTable
[
sound
],
0
);
if
((
SoundMode
!=
sdm_Off
)
&&
!
s
)
Quit
(
"SD_PlaySound() - Uncached sound"
);
if
((
DigiMode
!=
sds_Off
)
&&
(
DigiMap
[
sound
]
!=
-
1
))
{
if
((
DigiMode
==
sds_PC
)
&&
(
SoundMode
==
sdm_PC
))
{
if
(
s
->
priority
<
SoundPriority
)
return
(
false
);
SDL_PCStopSound
();
SD_PlayDigitized
(
DigiMap
[
sound
],
lp
,
rp
);
SoundPositioned
=
ispos
;
SoundNumber
=
sound
;
SoundPriority
=
s
->
priority
;
}
else
{
asm
pushf
asm
cli
if
(
DigiPriority
&&
!
DigiNumber
)
{
asm
popf
Quit
(
"SD_PlaySound: Priority without a sound"
);
}
asm
popf
if
(
s
->
priority
<
DigiPriority
)
return
(
false
);
SD_PlayDigitized
(
DigiMap
[
sound
],
lp
,
rp
);
SoundPositioned
=
ispos
;
DigiNumber
=
sound
;
DigiPriority
=
s
->
priority
;
}
return
(
true
);
}
if
(
SoundMode
==
sdm_Off
)
return
(
false
);
if
(
!
s
->
length
)
Quit
(
"SD_PlaySound() - Zero length sound"
);
if
(
s
->
priority
<
SoundPriority
)
return
(
false
);
switch
(
SoundMode
)
{
case
sdm_PC
:
SDL_PCPlaySound
((
void
*
)
s
);
break
;
case
sdm_AdLib
:
SDL_ALPlaySound
((
void
*
)
s
);
break
;
}
SoundNumber
=
sound
;
SoundPriority
=
s
->
priority
;
return
(
false
);
}
///////////////////////////////////////////////////////////////////////////
//
// SD_SoundPlaying() - returns the sound number that's playing, or 0 if
// no sound is playing
//
///////////////////////////////////////////////////////////////////////////
word
SD_SoundPlaying
(
void
)
{
boolean
result
=
false
;
switch
(
SoundMode
)
{
case
sdm_PC
:
result
=
pcSound
?
true
:
false
;
break
;
case
sdm_AdLib
:
result
=
alSound
?
true
:
false
;
break
;
}
if
(
result
)
return
(
SoundNumber
);
else
return
(
false
);
}
///////////////////////////////////////////////////////////////////////////
//
// SD_StopSound() - if a sound is playing, stops it
//
///////////////////////////////////////////////////////////////////////////
void
SD_StopSound
(
void
)
{
if
(
DigiPlaying
)
SD_StopDigitized
();
switch
(
SoundMode
)
{
case
sdm_PC
:
SDL_PCStopSound
();
break
;
case
sdm_AdLib
:
SDL_ALStopSound
();
break
;
}
SoundPositioned
=
false
;
SDL_SoundFinished
();
}
///////////////////////////////////////////////////////////////////////////
//
// SD_WaitSoundDone() - waits until the current sound is done playing
//
///////////////////////////////////////////////////////////////////////////
void
SD_WaitSoundDone
(
void
)
{
while
(
SD_SoundPlaying
())
;
}
///////////////////////////////////////////////////////////////////////////
//
// SD_MusicOn() - turns on the sequencer
//
///////////////////////////////////////////////////////////////////////////
void
SD_MusicOn
(
void
)
{
sqActive
=
true
;
}
///////////////////////////////////////////////////////////////////////////
//
// SD_MusicOff() - turns off the sequencer and any playing notes
//
///////////////////////////////////////////////////////////////////////////
void
SD_MusicOff
(
void
)
{
word
i
;
switch
(
MusicMode
)
{
case
smm_AdLib
:
alFXReg
=
0
;
alOut
(
alEffects
,
0
);
for
(
i
=
0
;
i
<
sqMaxTracks
;
i
++
)
alOut
(
alFreqH
+
i
+
1
,
0
);
break
;
}
sqActive
=
false
;
}
///////////////////////////////////////////////////////////////////////////
//
// SD_StartMusic() - starts playing the music pointed to
//
///////////////////////////////////////////////////////////////////////////
void
SD_StartMusic
(
MusicGroup
*
music
)
{
SD_MusicOff
();
asm
pushf
asm
cli
if
(
MusicMode
==
smm_AdLib
)
{
sqHackPtr
=
sqHack
=
music
->
values
;
sqHackSeqLen
=
sqHackLen
=
music
->
length
;
sqHackTime
=
0
;
alTimeCount
=
0
;
SD_MusicOn
();
}
asm
popf
}
///////////////////////////////////////////////////////////////////////////
//
// SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()
// to see if the fadeout is complete
//
///////////////////////////////////////////////////////////////////////////
void
SD_FadeOutMusic
(
void
)
{
switch
(
MusicMode
)
{
case
smm_AdLib
:
// DEBUG - quick hack to turn the music off
SD_MusicOff
();
break
;
}
}
///////////////////////////////////////////////////////////////////////////
//
// SD_MusicPlaying() - returns true if music is currently playing, false if
// not
//
///////////////////////////////////////////////////////////////////////////
boolean
SD_MusicPlaying
(
void
)
{
boolean
result
;
switch
(
MusicMode
)
{
case
smm_AdLib
:
result
=
false
;
// DEBUG - not written
break
;
default:
result
=
false
;
}
return
(
result
);
}
}
src/id_sd.h
View file @
55edef7f
//
#ifndef __ID_SD_H__
// ID Engine
#define __ID_SD_H__
// ID_SD.h - Sound Manager Header
// Version for Wolfenstein
// By Jason Blochowiak
//
#ifndef __ID_SD__
#define __ID_SD__
void
alOut
(
byte
n
,
byte
b
);
#define TickBase 70 // 70Hz per tick - used as a base for timer 0
#define TickBase 70 // 70Hz per tick - used as a base for timer 0
typedef
enum
{
typedef
enum
{
sdm_Off
,
sdm_Off
,
sdm_PC
,
sdm_AdLib
sdm_PC
,
sdm_AdLib
,
}
SDMode
;
}
SDMode
;
typedef
enum
{
typedef
enum
{
smm_Off
,
smm_AdLib
smm_Off
,
smm_AdLib
}
SMMode
;
}
SMMode
;
typedef
enum
{
typedef
enum
{
sds_Off
,
sds_PC
,
sds_SoundSource
,
sds_SoundBlaster
sds_Off
,
sds_PC
,
sds_SoundSource
,
sds_SoundBlaster
...
@@ -222,5 +213,6 @@ extern void SD_SetDigiDevice(SDSMode),
...
@@ -222,5 +213,6 @@ extern void SD_SetDigiDevice(SDSMode),
SD_StopDigitized
(
void
),
SD_StopDigitized
(
void
),
SD_Poll
(
void
);
SD_Poll
(
void
);
#elif
#error "fix me TODO"
#endif
#endif
src/id_sd_a.asm
deleted
100644 → 0
View file @
7d7c4678
;
; ID_SD_A.ASM
; Id Sound Manager assembly stuff
.
286
C
IDEAL
MODEL
MEDIUM
,
C
JUMPS
INCLUDE
'
ID_SD
.
EQU
'
DEBUG
=
0
EXTRN
SDL_DigitizedDone
:
FAR
EXTRN
alOut
:
FAR
;============================================================================
DATASEG
EXTRN
sqActive
:
WORD
EXTRN
ssSample
:
DWORD
EXTRN
ssLengthLeft
:
WORD
EXTRN
ssControl
:
WORD
EXTRN
ssStatus
:
WORD
EXTRN
ssData
:
WORD
EXTRN
ssOn
:
BYTE
EXTRN
ssOff
:
BYTE
EXTRN
pcSound
:
DWORD
EXTRN
pcLengthLeft
:
WORD
EXTRN
pcLastSample
:
BYTE
EXTRN
pcSoundLookup
:
WORD
EXTRN
alSound
:
DWORD
EXTRN
alBlock
:
WORD
EXTRN
alLengthLeft
:
WORD
EXTRN
alTimeCount
:
DWORD
EXTRN
sqHack
:
DWORD
EXTRN
sqHackPtr
:
DWORD
EXTRN
sqHackLen
:
WORD
EXTRN
sqHackSeqLen
:
WORD
EXTRN
sqHackTime
:
DWORD
EXTRN
HackCount
:
WORD
EXTRN
TimeCount
:
WORD
EXTRN
LocalTime
:
WORD
EXTRN
TimerCount
:
WORD
EXTRN
TimerDivisor
:
WORD
EXTRN
t0OldService
:
DWORD
EXTRN
SoundMode
:
WORD
EXTRN
DigiMode
:
WORD
EXTRN
SoundNumber
:
WORD
EXTRN
SoundPriority
:
WORD
count_time
dw
?
count_fx
dw
?
pcdtab
db
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
db
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
db
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
db
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
db
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
db
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
db
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
db
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
,
00
b
db
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
db
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
db
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
db
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
db
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
db
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
db
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
db
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
,
10
b
;============================================================================
CODESEG
MyDS
dw
?
pcindicate
dw
?
extreme
dw
?
PROC
SDL_SetDS
PUBLIC
SDL_SetDS
mov
ax
,
ds
mov
[
cs
:
MyDS
]
,
ds
ret
ENDP
;
; COMMONSTART
; Macro used for common prefix code
;
MACRO
COMMONSTART
IF
DEBUG
push
dx
push
ax
mov
dx
,
STATUS_REGISTER_1
in
al
,
dx
mov
dx
,
ATR_INDEX
mov
al
,
ATR_OVERSCAN
out
dx
,
al
mov
al
,
4
; red
out
dx
,
al
ENDIF
push
ds
push
ax
mov
ds
,
[
cs
:
MyDS
]
inc
[HackCount]
ENDM
;
; DOFX
; Macro used to do the sound effects code
;
MACRO
DOFX
les
di
,[pcSound]
; PC sound effects
mov
ax
,
es
or
ax
,
di
jz
@@
nopc
; nil pointer - no PC sound effect going
mov
bl
,
[
es
:
di
]
; Get the byte
inc
[
WORD
PTR
pcSound
]
; Increment pointer
cmp
[pcLastSample],
bl
; Is this sample the same as last?
jz
@@
pcsame
; Yep - don't do anything
mov
[pcLastSample],
bl
; No, save it for next time
or
bl
,
bl
jz
@@
pcoff
; If 0, turn sounds off
xor
bh
,
bh
shl
bx
,
1
mov
bx
,
[
pcSoundLookup
+
bx
]
; Use byte as index into frequency table
mov
al
,
0
b6h
; Write to channel 2 (speaker) timer
out
pcTAccess
,
al
mov
al
,
bl
out
pcTimer
,
al
; Low byte
mov
al
,
bh
out
pcTimer
,
al
; High byte
in
al
,
pcSpeaker
; Turn the speaker & gate on
or
al
,
3
out
pcSpeaker
,
al
jmp
@@
pcsame
@@
pcoff
:
in
al
,
pcSpeaker
; Turn the speaker & gate off
and
al
,
0
fch
; ~3
out
pcSpeaker
,
al
@@
pcsame
:
dec
[pcLengthLeft]
; Decrement length
jnz
@@
nopc
; If not 0, we're not done with the sound
mov
ax
,
0
mov
[
WORD
PTR
pcSound
]
,
ax
; Zero the pointer
mov
[
WORD
PTR
pcSound
+
2
]
,
ax
mov
[SoundNumber],
ax
; Indicate no sound
mov
[SoundPriority],
ax
; with no priority
in
al
,
pcSpeaker
; Turn the speaker off
and
al
,
0
fdh
; ~2
out
pcSpeaker
,
al
@@
nopc
:
les
di
,[alSound]
; AdLib sound effects
mov
ax
,
es
or
ax
,
di
jz
@@
noal
; nil pointer - no AdLib effect going
xor
ah
,
ah
mov
al
,
[
es
:
di
]
or
al
,
al
jz
@@
aldone
CALL
alOut
C
,
alFreqL
,
ax
mov
ax
,[alBlock]
@@
aldone
:
CALL
alOut
C
,
alFreqH
,
ax
inc
[
WORD
PTR
alSound
]
dec
[alLengthLeft]
jnz
@@
noal
mov
ax
,
0
mov
[
WORD
PTR
alSound
]
,
ax
; Zero the pointer
mov
[
WORD
PTR
alSound
+
2
]
,
ax
mov
[SoundNumber],
ax
; Indicate no sound
mov
[SoundPriority],
ax
; with no priority
CALL
alOut
C
,
alFreqH
,
ax
; Turn off the sound
@@
noal
:
ENDM
;
;
;
MACRO
TIME
cmp
[
count_time
]
,
2
jb
@@
notime
add
[LocalTime],
1
adc
[
LocalTime
+
2
]
,
0
add
[TimeCount],
1
adc
[
TimeCount
+
2
]
,
0
mov
[
count_time
]
,
0
@@
notime
:
ENDM
;
; COMMONEND
; Macro used for common suffix code
;
MACRO
COMMONEND
@@
fullexit
:
pop
es
popa
@@
nosave
:
mov
ax
,[TimerDivisor]
add
[TimerCount],
ax
jnc
@@
myack
pushf
call
[t0OldService]
jmp
@@
out
@@
myack
:
mov
al
,
20
h
out
20
h
,
al
@@
out
:
pop
ax
pop
ds
IF
DEBUG
mov
dx
,
STATUS_REGISTER_1
in
al
,
dx
mov
dx
,
ATR_INDEX
mov
al
,
ATR_OVERSCAN
out
dx
,
al
mov
al
,
3
; blue
out
dx
,
al
mov
al
,
20
h
; normal
out
dx
,
al
pop
ax
pop
dx
ENDIF
iret
ENDM
;
; SDL_IndicatePC
;
PROC
SDL_IndicatePC
on
:
WORD
PUBLIC
SDL_IndicatePC
mov
ax
,[on]
mov
[
cs
:
pcindicate
]
,
ax
ret
ENDP
;
; SDL_t0ExtremeAsmService
; Timer 0 ISR 7000Hz interrupts
;
PROC
SDL_t0ExtremeAsmService
PUBLIC
SDL_t0ExtremeAsmService
push
ax
mov
al
,
[
BYTE
PTR
cs
:
pcindicate
]
or
al
,
al
jz
@@
done
push
ds
push
es
pusha
mov
ds
,
[
cs
:
MyDS
]
les
di
,[pcSound]
mov
ax
,
es
or
ax
,
di
jz
@@
donereg
; nil pointer
mov
bl
,
[
es
:
di
]
; Get the byte
inc
[
WORD
PTR
pcSound
]
; Increment pointer
and
bl
,
11100000
b
; Nuke some of the precision (DEBUG - do this in the table)
xor
bh
,
bh
mov
ah
,
[
pcdtab
+
bx
]
; Translate the byte
in
al
,
pcSpeaker
and
al
,
11111100
b
or
al
,
ah
out
pcSpeaker
,
al
dec
[pcLengthLeft]
jnz
@@
donereg
mov
[
WORD
PTR
pcSound
]
,
0
; We're done with this sample
mov
[
WORD
PTR
pcSound
+
2
]
,
0
in
al
,
pcSpeaker
and
al
,
11111100
b
out
pcSpeaker
,
al
call
SDL_DigitizedDone
@@
donereg
:
popa
pop
es
pop
ds
@@
done
:
inc
[
cs
:
extreme
]
cmp
[
cs
:
extreme
]
,
10
jae
@@
tofast
mov
al
,
20
h
out
20
h
,
al
pop
ax
iret
@@
tofast
:
mov
[
cs
:
extreme
]
,
0
pop
ax
; jmp SDL_t0FastAsmService ; Drops through to SDL_t0FastAsmService
ENDP
;
; SDL_t0FastAsmService
; Timer 0 ISR for 700Hz interrupts
;
PROC
SDL_t0FastAsmService
PUBLIC
SDL_t0FastAsmService
COMMONSTART
inc
[
count_fx
]
; Time to do PC/AdLib effects & time?
cmp
[
count_fx
]
,
5
jae
@@
dofull
mov
ax
,[sqActive]
; Is the sequencer active?
or
ax
,
ax
jnz
@@
dofull
mov
ax
,
[
WORD
PTR
ssSample
]
; Is there a sample for the Sound Src?
or
ax
,
[
WORD
PTR
ssSample
+
2
]
jz
@@
nosave
@@
dofull
:
pusha
push
es
cmp
[
count_fx
]
,
5
jb
@@
nofx
mov
[
count_fx
]
,
0
DOFX
inc
[
count_time
]
TIME
@@
nofx
:
mov
ax
,[sqActive]
or
ax
,
ax
jz
@@
nosq
mov
ax
,[sqHackLen]
or
ax
,
ax
jz
@@
sqdone
les
di
,[sqHackPtr]
@@
sqloop
:
mov
ax
,
[
WORD
PTR
sqHackTime
+
2
]
cmp
ax
,
[
WORD
PTR
alTimeCount
+
2
]
ja
@@
sqdone
mov
ax
,
[
WORD
PTR
sqHackTime
]
cmp
ax
,
[
WORD
PTR
alTimeCount
]
ja
@@
sqdone
mov
ax
,
[
es
:
di
+
2
]
; Get time to next event
add
ax
,
[
WORD
PTR
alTimeCount
]
mov
[
WORD
PTR
sqHackTime
]
,
ax
mov
ax
,
[
WORD
PTR
alTimeCount
+
2
]
adc
ax
,
0
mov
[
WORD
PTR
sqHackTime
+
2
]
,
ax
mov
ax
,
[
es
:
di
]
; Get register/value pair
xor
bh
,
bh
mov
bl
,
ah
xor
ah
,
ah
CALL
alOut
C
,
ax
,
bx
add
di
,
4
mov
[
WORD
PTR
sqHackPtr
]
,
di
sub
[sqHackLen],
4
jnz
@@
sqloop
@@
sqdone
:
add
[
WORD
PTR
alTimeCount
]
,
1
adc
[
WORD
PTR
alTimeCount
+
2
]
,
0
mov
ax
,[sqHackLen]
or
ax
,
ax
jnz
@@
nosq
mov
ax
,
[
WORD
PTR
sqHack
]
; Copy pointer
mov
[
WORD
PTR
sqHackPtr
]
,
ax
mov
ax
,
[
WORD
PTR
sqHack
+
2
]
mov
[
WORD
PTR
sqHackPtr
+
2
]
,
ax
mov
ax
,[sqHackSeqLen]
; Copy length
mov
[sqHackLen],
ax
mov
ax
,
0
mov
[
WORD
PTR
alTimeCount
]
,
ax
; Reset time counts
mov
[
WORD
PTR
alTimeCount
+
2
]
,
ax
mov
[
WORD
PTR
sqHackTime
]
,
ax
mov
[
WORD
PTR
sqHackTime
+
2
]
,
ax
@@
nosq
:
les
di
,[ssSample]
; Get pointer to Sound Source sample
mov
ax
,
es
or
ax
,
di
jz
@@
ssdone
; If nil, skip this
@@
ssloop
:
mov
dx
,[ssStatus]
; Check to see if FIFO has any empty slots
in
al
,
dx
test
al
,
40
h
jnz
@@
ssdone
; Nope - don't push any more data out
mov
dx
,[ssData]
mov
al
,
[
es
:
di
]
; al = *ssSample
out
dx
,
al
; Pump the value out
mov
dx
,[ssControl]
; Pulse printer select
mov
al
,[ssOff]
out
dx
,
al
push
ax
pop
ax
mov
al
,[ssOn]
out
dx
,
al
push
ax
; Delay a short while
pop
ax
inc
di
mov
[
WORD
PTR
ssSample
]
,
di
; ssSample++
dec
[ssLengthLeft]
jnz
@@
ssloop
mov
[
WORD
PTR
ssSample
]
,
0
; We're done with this sample
mov
[
WORD
PTR
ssSample
+
2
]
,
0
call
SDL_DigitizedDone
@@
ssdone
:
COMMONEND
ENDP
;
; SDL_t0SlowAsmService
; Timer 0 ISR for 140Hz interrupts
;
PROC
SDL_t0SlowAsmService
PUBLIC
SDL_t0SlowAsmService
IF
DEBUG
push
dx
push
ax
mov
dx
,
STATUS_REGISTER_1
in
al
,
dx
mov
dx
,
ATR_INDEX
mov
al
,
ATR_OVERSCAN
out
dx
,
al
mov
al
,
4
; red
out
dx
,
al
ENDIF
push
ds
push
ax
mov
ds
,
[
cs
:
MyDS
]
inc
[
count_time
]
TIME
mov
ax
,
[
WORD
PTR
pcSound
]
; Is there a PC sound effect going?
or
ax
,
[
WORD
PTR
pcSound
+
2
]
jnz
@@
dofull
mov
ax
,
[
WORD
PTR
alSound
]
; Is there an AdLib sound effect going?
or
ax
,
[
WORD
PTR
alSound
+
2
]
jz
@@
nosave
@@
dofull
:
pusha
push
es
DOFX
COMMONEND
ENDP
END
src/id_vl.c
View file @
55edef7f
/* id_vl.c */
/* id_vl.c */
#include <dos.h>
#include <alloc.h>
#include <mem.h>
#include <string.h>
#include "id_heads.h"
#include "id_heads.h"
//
// SC_INDEX is expected to stay at SC_MAPMASK for proper operation
//
unsigned
bufferofs
;
unsigned
bufferofs
;
unsigned
displayofs
;
unsigned
displayofs
;
...
@@ -20,92 +12,34 @@ unsigned ylookup[MAXSCANLINES];
...
@@ -20,92 +12,34 @@ unsigned ylookup[MAXSCANLINES];
boolean
screenfaded
;
boolean
screenfaded
;
boolean
fastpalette
;
// if true, use outsb to set
byte
palette1
[
256
][
3
],
palette2
[
256
][
3
];
byte
palette1
[
256
][
3
],
far
palette2
[
256
][
3
];
//===========================================================================
int
VL_VideoID
(
void
);
void
VL_SetCRTC
(
int
crtc
);
void
VL_WaitVBL
(
int
vbls
);
//===========================================================================
/*
=======================
=
= VL_Startup // WOLFENSTEIN HACK
=
=======================
*/
static
char
*
ParmStrings
[]
=
{
"HIDDENCARD"
,
""
};
void
VL_Startup
(
void
)
{
int
i
,
videocard
;
asm
cld
;
videocard
=
VL_VideoID
();
for
(
i
=
1
;
i
<
_argc
;
i
++
)
if
(
US_CheckParm
(
_argv
[
i
],
ParmStrings
)
==
0
)
{
videocard
=
5
;
break
;
}
if
(
videocard
!=
5
)
Quit
(
"Improper video card! If you really have a VGA card that I am not
\n
"
"detecting, use the -HIDDENCARD command line parameter!"
);
}
/*
=======================
=
= VL_Shutdown
=
=======================
*/
void
VL_Shutdown
(
void
)
void
VL_WaitVBL
(
int
vbls
)
{
{
VL_SetTextMode
();
}
}
/*
/*
=======================
=======================
=
=
= VL_S
etVGAPlaneMode
= VL_S
tartup
=
=
=======================
=======================
*/
*/
void
VL_SetVGAPlaneMode
(
void
)
void
VL_Startup
(
void
)
{
{
asm
mov
ax
,
0x13
asm
int
0x10
VL_DePlaneVGA
();
VGAMAPMASK
(
15
);
VL_SetLineWidth
(
40
);
}
}
/*
/*
=======================
=======================
=
=
= VL_S
etTextMode
= VL_S
hutdown
=
=
=======================
=======================
*/
*/
void
VL_SetTextMode
(
void
)
void
VL_Shutdown
(
void
)
{
{
asm
mov
ax
,
3
asm
int
0x10
}
}
//===========================================================================
//===========================================================================
...
@@ -122,143 +56,8 @@ asm int 0x10
...
@@ -122,143 +56,8 @@ asm int 0x10
void
VL_ClearVideo
(
byte
color
)
void
VL_ClearVideo
(
byte
color
)
{
{
asm
mov
dx
,
GC_INDEX
asm
mov
al
,
GC_MODE
asm
out
dx
,
al
asm
inc
dx
asm
in
al
,
dx
asm
and
al
,
0xfc
// write mode 0 to store directly to video
asm
out
dx
,
al
asm
mov
dx
,
SC_INDEX
asm
mov
ax
,
SC_MAPMASK
+
15
*
256
asm
out
dx
,
ax
// write through all four planes
asm
mov
ax
,
SCREENSEG
asm
mov
es
,
ax
asm
mov
al
,[
color
]
asm
mov
ah
,
al
asm
mov
cx
,
0x8000
// 0x8000 words, clearing 8 video bytes/word
asm
xor
di
,
di
asm
rep
stosw
}
}
/*
=============================================================================
VGA REGISTER MANAGEMENT ROUTINES
=============================================================================
*/
/*
=================
=
= VL_DePlaneVGA
=
=================
*/
void
VL_DePlaneVGA
(
void
)
{
//
// change CPU addressing to non linear mode
//
//
// turn off chain 4 and odd/even
//
outportb
(
SC_INDEX
,
SC_MEMMODE
);
outportb
(
SC_INDEX
+
1
,(
inportb
(
SC_INDEX
+
1
)
&~
8
)
|
4
);
outportb
(
SC_INDEX
,
SC_MAPMASK
);
// leave this set throughought
//
// turn off odd/even and set write mode 0
//
outportb
(
GC_INDEX
,
GC_MODE
);
outportb
(
GC_INDEX
+
1
,
inportb
(
GC_INDEX
+
1
)
&~
0x13
);
//
// turn off chain
//
outportb
(
GC_INDEX
,
GC_MISCELLANEOUS
);
outportb
(
GC_INDEX
+
1
,
inportb
(
GC_INDEX
+
1
)
&~
2
);
//
// clear the entire buffer space, because int 10h only did 16 k / plane
//
VL_ClearVideo
(
0
);
//
// change CRTC scanning from doubleword to byte mode, allowing >64k scans
//
outportb
(
CRTC_INDEX
,
CRTC_UNDERLINE
);
outportb
(
CRTC_INDEX
+
1
,
inportb
(
CRTC_INDEX
+
1
)
&~
0x40
);
outportb
(
CRTC_INDEX
,
CRTC_MODE
);
outportb
(
CRTC_INDEX
+
1
,
inportb
(
CRTC_INDEX
+
1
)
|
0x40
);
}
//===========================================================================
/*
====================
=
= VL_SetLineWidth
=
= Line witdh is in WORDS, 40 words is normal width for vgaplanegr
=
====================
*/
void
VL_SetLineWidth
(
unsigned
width
)
{
int
i
,
offset
;
//
// set wide virtual screen
//
outport
(
CRTC_INDEX
,
CRTC_OFFSET
+
width
*
256
);
//
// set up lookup tables
//
linewidth
=
width
*
2
;
offset
=
0
;
for
(
i
=
0
;
i
<
MAXSCANLINES
;
i
++
)
{
ylookup
[
i
]
=
offset
;
offset
+=
linewidth
;
}
}
/*
====================
=
= VL_SetSplitScreen
=
====================
*/
void
VL_SetSplitScreen
(
int
linenum
)
{
VL_WaitVBL
(
1
);
linenum
=
linenum
*
2
-
1
;
outportb
(
CRTC_INDEX
,
CRTC_LINECOMPARE
);
outportb
(
CRTC_INDEX
+
1
,
linenum
%
256
);
outportb
(
CRTC_INDEX
,
CRTC_OVERFLOW
);
outportb
(
CRTC_INDEX
+
1
,
1
+
16
*
(
linenum
/
256
));
outportb
(
CRTC_INDEX
,
CRTC_MAXSCANLINE
);
outportb
(
CRTC_INDEX
+
1
,
inportb
(
CRTC_INDEX
+
1
)
&
(
255
-
64
));
}
/*
/*
=============================================================================
=============================================================================
...
@@ -280,15 +79,6 @@ void VL_SetSplitScreen (int linenum)
...
@@ -280,15 +79,6 @@ void VL_SetSplitScreen (int linenum)
void
VL_FillPalette
(
int
red
,
int
green
,
int
blue
)
void
VL_FillPalette
(
int
red
,
int
green
,
int
blue
)
{
{
int
i
;
outportb
(
PEL_WRITE_ADR
,
0
);
for
(
i
=
0
;
i
<
256
;
i
++
)
{
outportb
(
PEL_DATA
,
red
);
outportb
(
PEL_DATA
,
green
);
outportb
(
PEL_DATA
,
blue
);
}
}
}
//===========================================================================
//===========================================================================
...
@@ -301,12 +91,8 @@ void VL_FillPalette (int red, int green, int blue)
...
@@ -301,12 +91,8 @@ void VL_FillPalette (int red, int green, int blue)
=================
=================
*/
*/
void
VL_SetColor
(
int
color
,
int
red
,
int
green
,
int
blue
)
void
VL_SetColor
(
int
color
,
int
red
,
int
green
,
int
blue
)
{
{
outportb
(
PEL_WRITE_ADR
,
color
);
outportb
(
PEL_DATA
,
red
);
outportb
(
PEL_DATA
,
green
);
outportb
(
PEL_DATA
,
blue
);
}
}
//===========================================================================
//===========================================================================
...
@@ -319,12 +105,8 @@ void VL_SetColor (int color, int red, int green, int blue)
...
@@ -319,12 +105,8 @@ void VL_SetColor (int color, int red, int green, int blue)
=================
=================
*/
*/
void
VL_GetColor
(
int
color
,
int
*
red
,
int
*
green
,
int
*
blue
)
void
VL_GetColor
(
int
color
,
int
*
red
,
int
*
green
,
int
*
blue
)
{
{
outportb
(
PEL_READ_ADR
,
color
);
*
red
=
inportb
(
PEL_DATA
);
*
green
=
inportb
(
PEL_DATA
);
*
blue
=
inportb
(
PEL_DATA
);
}
}
//===========================================================================
//===========================================================================
...
@@ -340,47 +122,8 @@ void VL_GetColor (int color, int *red, int *green, int *blue)
...
@@ -340,47 +122,8 @@ void VL_GetColor (int color, int *red, int *green, int *blue)
=================
=================
*/
*/
void
VL_SetPalette
(
byte
far
*
palette
)
void
VL_SetPalette
(
byte
*
palette
)
{
{
int
i
;
// outportb (PEL_WRITE_ADR,0);
// for (i=0;i<768;i++)
// outportb(PEL_DATA,*palette++);
asm
mov
dx
,
PEL_WRITE_ADR
asm
mov
al
,
0
asm
out
dx
,
al
asm
mov
dx
,
PEL_DATA
asm
lds
si
,[
palette
]
asm
test
[
ss
:
fastpalette
],
1
asm
jz
slowset
//
// set palette fast for cards that can take it
//
asm
mov
cx
,
768
asm
rep
outsb
asm
jmp
done
//
// set palette slowly for some video cards
//
slowset:
asm
mov
cx
,
256
setloop:
asm
lodsb
asm
out
dx
,
al
asm
lodsb
asm
out
dx
,
al
asm
lodsb
asm
out
dx
,
al
asm
loop
setloop
done:
asm
mov
ax
,
ss
asm
mov
ds
,
ax
}
}
...
@@ -397,13 +140,8 @@ done:
...
@@ -397,13 +140,8 @@ done:
=================
=================
*/
*/
void
VL_GetPalette
(
byte
far
*
palette
)
void
VL_GetPalette
(
byte
*
palette
)
{
{
int
i
;
outportb
(
PEL_READ_ADR
,
0
);
for
(
i
=
0
;
i
<
768
;
i
++
)
*
palette
++
=
inportb
(
PEL_DATA
);
}
}
...
@@ -419,14 +157,14 @@ void VL_GetPalette (byte far *palette)
...
@@ -419,14 +157,14 @@ void VL_GetPalette (byte far *palette)
=================
=================
*/
*/
void
VL_FadeOut
(
int
start
,
int
end
,
int
red
,
int
green
,
int
blue
,
int
steps
)
void
VL_FadeOut
(
int
start
,
int
end
,
int
red
,
int
green
,
int
blue
,
int
steps
)
{
{
int
i
,
j
,
orig
,
delta
;
int
i
,
j
,
orig
,
delta
;
byte
far
*
origptr
,
far
*
newptr
;
byte
*
origptr
,
*
newptr
;
VL_WaitVBL
(
1
);
VL_WaitVBL
(
1
);
VL_GetPalette
(
&
palette1
[
0
][
0
]);
VL_GetPalette
(
&
palette1
[
0
][
0
]);
_f
memcpy
(
palette2
,
palette1
,
768
);
memcpy
(
palette2
,
palette1
,
768
);
//
//
// fade through intermediate frames
// fade through intermediate frames
...
@@ -469,13 +207,13 @@ void VL_FadeOut (int start, int end, int red, int green, int blue, int steps)
...
@@ -469,13 +207,13 @@ void VL_FadeOut (int start, int end, int red, int green, int blue, int steps)
=================
=================
*/
*/
void
VL_FadeIn
(
int
start
,
int
end
,
byte
far
*
palette
,
int
steps
)
void
VL_FadeIn
(
int
start
,
int
end
,
byte
*
palette
,
int
steps
)
{
{
int
i
,
j
,
delta
;
int
i
,
j
,
delta
;
VL_WaitVBL
(
1
);
VL_WaitVBL
(
1
);
VL_GetPalette
(
&
palette1
[
0
][
0
]);
VL_GetPalette
(
&
palette1
[
0
][
0
]);
_f
memcpy
(
&
palette2
[
0
][
0
],
&
palette1
[
0
][
0
],
sizeof
(
palette1
));
memcpy
(
&
palette2
[
0
][
0
],
&
palette1
[
0
][
0
],
sizeof
(
palette1
));
start
*=
3
;
start
*=
3
;
end
=
end
*
3
+
2
;
end
=
end
*
3
+
2
;
...
@@ -502,34 +240,6 @@ void VL_FadeIn (int start, int end, byte far *palette, int steps)
...
@@ -502,34 +240,6 @@ void VL_FadeIn (int start, int end, byte far *palette, int steps)
screenfaded
=
false
;
screenfaded
=
false
;
}
}
/*
=================
=
= VL_TestPaletteSet
=
= Sets the palette with outsb, then reads it in and compares
= If it compares ok, fastpalette is set to true.
=
=================
*/
void
VL_TestPaletteSet
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
768
;
i
++
)
palette1
[
0
][
i
]
=
i
;
fastpalette
=
true
;
VL_SetPalette
(
&
palette1
[
0
][
0
]);
VL_GetPalette
(
&
palette2
[
0
][
0
]);
if
(
_fmemcmp
(
&
palette1
[
0
][
0
],
&
palette2
[
0
][
0
],
768
))
fastpalette
=
false
;
}
/*
/*
==================
==================
=
=
...
@@ -540,15 +250,8 @@ void VL_TestPaletteSet (void)
...
@@ -540,15 +250,8 @@ void VL_TestPaletteSet (void)
void
VL_ColorBorder
(
int
color
)
void
VL_ColorBorder
(
int
color
)
{
{
_AH
=
0x10
;
_AL
=
1
;
_BH
=
color
;
geninterrupt
(
0x10
);
bordercolor
=
color
;
}
}
/*
/*
=============================================================================
=============================================================================
...
@@ -569,14 +272,9 @@ byte rightmasks[4] = {1,3,7,15};
...
@@ -569,14 +272,9 @@ byte rightmasks[4] = {1,3,7,15};
=================
=================
*/
*/
void
VL_Plot
(
int
x
,
int
y
,
int
color
)
void
VL_Plot
(
int
x
,
int
y
,
int
color
)
{
{
byte
mask
;
*
(
gfxbuf
+
320
*
y
+
x
)
=
color
;
mask
=
pixmasks
[
x
&
3
];
VGAMAPMASK
(
mask
);
*
(
byte
far
*
)
MK_FP
(
SCREENSEG
,
bufferofs
+
(
ylookup
[
y
]
+
(
x
>>
2
)))
=
color
;
VGAMAPMASK
(
15
);
}
}
/*
/*
...
@@ -587,43 +285,11 @@ void VL_Plot (int x, int y, int color)
...
@@ -587,43 +285,11 @@ void VL_Plot (int x, int y, int color)
=================
=================
*/
*/
void
VL_Hlin
(
unsigned
x
,
unsigned
y
,
unsigned
width
,
unsigned
color
)
void
VL_Hlin
(
unsigned
x
,
unsigned
y
,
unsigned
width
,
unsigned
color
)
{
{
unsigned
xbyte
;
memset
(
gfxbuf
+
320
*
y
+
x
,
color
,
width
);
byte
far
*
dest
;
byte
leftmask
,
rightmask
;
int
midbytes
;
xbyte
=
x
>>
2
;
leftmask
=
leftmasks
[
x
&
3
];
rightmask
=
rightmasks
[(
x
+
width
-
1
)
&
3
];
midbytes
=
((
x
+
width
+
3
)
>>
2
)
-
xbyte
-
2
;
dest
=
MK_FP
(
SCREENSEG
,
bufferofs
+
ylookup
[
y
]
+
xbyte
);
if
(
midbytes
<
0
)
{
// all in one byte
VGAMAPMASK
(
leftmask
&
rightmask
);
*
dest
=
color
;
VGAMAPMASK
(
15
);
return
;
}
VGAMAPMASK
(
leftmask
);
*
dest
++
=
color
;
VGAMAPMASK
(
15
);
_fmemset
(
dest
,
color
,
midbytes
);
dest
+=
midbytes
;
VGAMAPMASK
(
rightmask
);
*
dest
=
color
;
VGAMAPMASK
(
15
);
}
}
/*
/*
=================
=================
=
=
...
@@ -634,23 +300,13 @@ void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color)
...
@@ -634,23 +300,13 @@ void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color)
void
VL_Vlin
(
int
x
,
int
y
,
int
height
,
int
color
)
void
VL_Vlin
(
int
x
,
int
y
,
int
height
,
int
color
)
{
{
byte
far
*
dest
,
mask
;
byte
*
ptr
=
gfxbuf
+
320
*
y
+
x
;
while
(
height
--
)
{
mask
=
pixmasks
[
x
&
3
];
*
ptr
=
color
;
VGAMAPMASK
(
mask
);
ptr
+=
320
;
dest
=
MK_FP
(
SCREENSEG
,
bufferofs
+
ylookup
[
y
]
+
(
x
>>
2
));
while
(
height
--
)
{
*
dest
=
color
;
dest
+=
linewidth
;
}
}
VGAMAPMASK
(
15
);
}
}
/*
/*
=================
=================
=
=
...
@@ -659,48 +315,13 @@ void VL_Vlin (int x, int y, int height, int color)
...
@@ -659,48 +315,13 @@ void VL_Vlin (int x, int y, int height, int color)
=================
=================
*/
*/
void
VL_Bar
(
int
x
,
int
y
,
int
width
,
int
height
,
int
color
)
void
VL_Bar
(
int
x
,
int
y
,
int
width
,
int
height
,
int
color
)
{
{
byte
far
*
dest
;
byte
*
ptr
=
gfxbuf
+
320
*
y
+
x
;
byte
leftmask
,
rightmask
;
while
(
height
--
)
{
int
midbytes
,
linedelta
;
memset
(
ptr
,
color
,
width
);
ptr
+=
320
;
leftmask
=
leftmasks
[
x
&
3
];
rightmask
=
rightmasks
[(
x
+
width
-
1
)
&
3
];
midbytes
=
((
x
+
width
+
3
)
>>
2
)
-
(
x
>>
2
)
-
2
;
linedelta
=
linewidth
-
(
midbytes
+
1
);
dest
=
MK_FP
(
SCREENSEG
,
bufferofs
+
ylookup
[
y
]
+
(
x
>>
2
));
if
(
midbytes
<
0
)
{
// all in one byte
VGAMAPMASK
(
leftmask
&
rightmask
);
while
(
height
--
)
{
*
dest
=
color
;
dest
+=
linewidth
;
}
VGAMAPMASK
(
15
);
return
;
}
}
while
(
height
--
)
{
VGAMAPMASK
(
leftmask
);
*
dest
++
=
color
;
VGAMAPMASK
(
15
);
_fmemset
(
dest
,
color
,
midbytes
);
dest
+=
midbytes
;
VGAMAPMASK
(
rightmask
);
*
dest
=
color
;
dest
+=
linedelta
;
}
VGAMAPMASK
(
15
);
}
}
/*
/*
...
@@ -719,8 +340,9 @@ void VL_Bar (int x, int y, int width, int height, int color)
...
@@ -719,8 +340,9 @@ void VL_Bar (int x, int y, int width, int height, int color)
=================
=================
*/
*/
void
VL_MemToLatch
(
byte
far
*
source
,
int
width
,
int
height
,
unsigne
d
dest
)
void
VL_MemToLatch
(
byte
*
source
,
int
width
,
int
height
,
wor
d
dest
)
{
{
#if 0
unsigned count;
unsigned count;
byte plane,mask;
byte plane,mask;
...
@@ -742,6 +364,7 @@ asm mov ds,ax
...
@@ -742,6 +364,7 @@ asm mov ds,ax
source+= count;
source+= count;
}
}
#endif
}
}
...
@@ -758,25 +381,13 @@ asm mov ds,ax
...
@@ -758,25 +381,13 @@ asm mov ds,ax
=================
=================
*/
*/
void
VL_MemToScreen
(
byte
far
*
source
,
int
width
,
int
height
,
int
x
,
int
y
)
void
VL_MemToScreen
(
byte
*
source
,
int
width
,
int
height
,
int
x
,
int
y
)
{
{
byte
far
*
screen
,
far
*
dest
,
mask
;
byte
*
ptr
=
gfxbuf
+
320
*
y
+
x
;
int
plane
;
while
(
height
--
)
{
memcpy
(
ptr
,
source
,
width
);
width
>>=
2
;
source
+=
width
;
dest
=
MK_FP
(
SCREENSEG
,
bufferofs
+
ylookup
[
y
]
+
(
x
>>
2
)
);
ptr
+=
320
;
mask
=
1
<<
(
x
&
3
);
for
(
plane
=
0
;
plane
<
4
;
plane
++
)
{
VGAMAPMASK
(
mask
);
mask
<<=
1
;
if
(
mask
==
16
)
mask
=
1
;
screen
=
dest
;
for
(
y
=
0
;
y
<
height
;
y
++
,
screen
+=
linewidth
,
source
+=
width
)
memcpy
(
screen
,
source
,
width
);
}
}
}
}
...
@@ -792,6 +403,7 @@ void VL_MemToScreen (byte far *source, int width, int height, int x, int y)
...
@@ -792,6 +403,7 @@ void VL_MemToScreen (byte far *source, int width, int height, int x, int y)
void
VL_LatchToScreen
(
unsigned
source
,
int
width
,
int
height
,
int
x
,
int
y
)
void
VL_LatchToScreen
(
unsigned
source
,
int
width
,
int
height
,
int
x
,
int
y
)
{
{
#if 0
VGAWRITEMODE(1);
VGAWRITEMODE(1);
VGAMAPMASK(15);
VGAMAPMASK(15);
...
@@ -823,6 +435,7 @@ asm mov ax,ss
...
@@ -823,6 +435,7 @@ asm mov ax,ss
asm mov ds,ax
asm mov ds,ax
VGAWRITEMODE(0);
VGAWRITEMODE(0);
#endif
}
}
/* ======================================================================== */
/* ======================================================================== */
...
...
src/id_vl.h
View file @
55edef7f
...
@@ -138,7 +138,7 @@ void VL_Bar (int x, int y, int width, int height, int color);
...
@@ -138,7 +138,7 @@ void VL_Bar (int x, int y, int width, int height, int color);
void
VL_MungePic
(
byte
*
source
,
unsigned
width
,
unsigned
height
);
void
VL_MungePic
(
byte
*
source
,
unsigned
width
,
unsigned
height
);
void
VL_DrawPicBare
(
int
x
,
int
y
,
byte
*
pic
,
int
width
,
int
height
);
void
VL_DrawPicBare
(
int
x
,
int
y
,
byte
*
pic
,
int
width
,
int
height
);
void
VL_MemToLatch
(
byte
*
source
,
int
width
,
int
height
,
unsigne
d
dest
);
void
VL_MemToLatch
(
byte
*
source
,
int
width
,
int
height
,
wor
d
dest
);
void
VL_ScreenToScreen
(
unsigned
source
,
unsigned
dest
,
int
width
,
int
height
);
void
VL_ScreenToScreen
(
unsigned
source
,
unsigned
dest
,
int
width
,
int
height
);
void
VL_MemToScreen
(
byte
*
source
,
int
width
,
int
height
,
int
x
,
int
y
);
void
VL_MemToScreen
(
byte
*
source
,
int
width
,
int
height
,
int
x
,
int
y
);
...
...
src/id_vl_a.asm
deleted
100644 → 0
View file @
7d7c4678
; ID_VL.ASM
IDEAL
MODEL
MEDIUM
,
C
INCLUDE
'
ID_VL
.
EQU
'
SCREENSEG
=
0
a000h
DATASEG
EXTRN
TimeCount
:
WORD
; incremented every 70th of a second
EXTRN
linewidth
:
WORD
starttime
dw
?
CODESEG
;===========================================================================
;==============
;
; VL_WaitVBL ******** NEW *********
;
; Wait for the vertical retrace (returns before the actual vertical sync)
;
;==============
PROC
VL_WaitVBL
num
:
WORD
PUBLIC
VL_WaitVBL
@@
wait
:
mov
dx
,
STATUS_REGISTER_1
mov
cx
,[num]
;
; wait for a display signal to make sure the raster isn't in the middle
; of a sync
;
@@
waitnosync
:
in
al
,
dx
test
al
,
8
jnz
@@
waitnosync
@@
waitsync
:
in
al
,
dx
test
al
,
8
jz
@@
waitsync
loop
@@
waitnosync
ret
ENDP
;===========================================================================
;==============
;
; VL_SetCRTC
;
;==============
PROC
VL_SetCRTC
crtc
:
WORD
PUBLIC
VL_SetCRTC
;
; wait for a display signal to make sure the raster isn't in the middle
; of a sync
;
cli
mov
dx
,
STATUS_REGISTER_1
@@
waitdisplay
:
in
al
,
dx
test
al
,
1
;1 = display is disabled (HBL / VBL)
jnz
@@
waitdisplay
;
; set CRTC start
;
; for some reason, my XT's EGA card doesn't like word outs to the CRTC
; index...
;
mov
cx
,[crtc]
mov
dx
,
CRTC_INDEX
mov
al
,
0
ch
;start address high register
out
dx
,
al
inc
dx
mov
al
,
ch
out
dx
,
al
dec
dx
mov
al
,
0
dh
;start address low register
out
dx
,
al
mov
al
,
cl
inc
dx
out
dx
,
al
sti
ret
ENDP
;===========================================================================
;==============
;
; VL_SetScreen
;
;==============
PROC
VL_SetScreen
crtc
:
WORD
,
pel
:
WORD
PUBLIC
VL_SetScreen
mov
cx
,[timecount]
; if timecount goes up by two, the retrace
add
cx
,
2
; period was missed (an interrupt covered it)
mov
dx
,
STATUS_REGISTER_1
;
; wait for a display signal to make sure the raster isn't in the middle
; of a sync
;
@@
waitdisplay
:
in
al
,
dx
test
al
,
1
;1 = display is disabled (HBL / VBL)
jnz
@@
waitdisplay
@@
loop
:
sti
jmp
$
+
2
cli
cmp
[timecount],
cx
; will only happen if an interrupt is
jae
@@
setcrtc
; straddling the entire retrace period
;
; when several succesive display not enableds occur,
; the bottom of the screen has been hit
;
in
al
,
dx
test
al
,
8
jnz
@@
waitdisplay
test
al
,
1
jz
@@
loop
in
al
,
dx
test
al
,
8
jnz
@@
waitdisplay
test
al
,
1
jz
@@
loop
in
al
,
dx
test
al
,
8
jnz
@@
waitdisplay
test
al
,
1
jz
@@
loop
in
al
,
dx
test
al
,
8
jnz
@@
waitdisplay
test
al
,
1
jz
@@
loop
in
al
,
dx
test
al
,
8
jnz
@@
waitdisplay
test
al
,
1
jz
@@
loop
@@
setcrtc
:
;
; set CRTC start
;
; for some reason, my XT's EGA card doesn't like word outs to the CRTC
; index...
;
mov
cx
,[crtc]
mov
dx
,
CRTC_INDEX
mov
al
,
0
ch
;start address high register
out
dx
,
al
inc
dx
mov
al
,
ch
out
dx
,
al
dec
dx
mov
al
,
0
dh
;start address low register
out
dx
,
al
mov
al
,
cl
inc
dx
out
dx
,
al
;
; set horizontal panning
;
mov
dx
,
ATR_INDEX
mov
al
,
ATR_PELPAN
or
20
h
out
dx
,
al
jmp
$
+
2
mov
al
,
[
BYTE
pel
]
;pel pan value
out
dx
,
al
sti
ret
ENDP
;===========================================================================
;============================================================================
;
; VL_ScreenToScreen
;
; Basic block copy routine. Copies one block of screen memory to another,
; using write mode 1 (sets it and returns with write mode 0). bufferofs is
; NOT accounted for.
;
;============================================================================
PROC
VL_ScreenToScreen
source
:
WORD
,
dest
:
WORD
,
wide
:
WORD
,
height
:
WORD
PUBLIC
VL_ScreenToScreen
USES
SI
,
DI
pushf
cli
mov
dx
,
SC_INDEX
mov
ax
,
SC_MAPMASK
+
15
*
256
out
dx
,
ax
mov
dx
,
GC_INDEX
mov
al
,
GC_MODE
out
dx
,
al
inc
dx
in
al
,
dx
and
al
,
NOT
3
or
al
,
1
out
dx
,
al
popf
mov
bx
,[linewidth]
sub
bx
,[wide]
mov
ax
,
SCREENSEG
mov
es
,
ax
mov
ds
,
ax
mov
si
,[source]
mov
di
,[dest]
;start at same place in all planes
mov
dx
,[height]
;scan lines to draw
mov
ax
,[wide]
@@
lineloop
:
mov
cx
,
ax
rep
movsb
add
si
,
bx
add
di
,
bx
dec
dx
jnz
@@
lineloop
mov
dx
,
GC_INDEX
+
1
in
al
,
dx
and
al
,
NOT
3
out
dx
,
al
mov
ax
,
ss
mov
ds
,
ax
;restore turbo's data segment
ret
ENDP
;===========================================================================
MASM
;
;
; Name: VL_VideoID
;
; Function: Detects the presence of various video subsystems
;
; int VideoID;
;
; Subsystem ID values:
; 0 = (none)
; 1 = MDA
; 2 = CGA
; 3 = EGA
; 4 = MCGA
; 5 = VGA
; 80h = HGC
; 81h = HGC+
; 82h = Hercules InColor
;
;
;
;
; Equates
;
;
VIDstruct
STRUC
; corresponds to C data structure
Video0Type
DB
?
; first subsystem type
Display0Type
DB
?
; display attached to first subsystem
Video1Type
DB
?
; second subsystem type
Display1Type
DB
?
; display attached to second subsystem
VIDstruct
ENDS
Device0
EQU
word
ptr
Video0Type
[di]
Device1
EQU
word
ptr
Video1Type
[di]
MDA
EQU
1
; subsystem types
CGA
EQU
2
EGA
EQU
3
MCGA
EQU
4
VGA
EQU
5
HGC
EQU
80
h
HGCPlus
EQU
81
h
InColor
EQU
82
h
MDADisplay
EQU
1
; display types
CGADisplay
EQU
2
EGAColorDisplay
EQU
3
PS2MonoDisplay
EQU
4
PS2ColorDisplay
EQU
5
TRUE
EQU
1
FALSE
EQU
0
;
;
; Program
;
;
Results
VIDstruct
<>
;results go here!
EGADisplays
DB
CGADisplay
; 0000b, 0001b (EGA switch values)
DB
EGAColorDisplay
; 0010b, 0011b
DB
MDADisplay
; 0100b, 0101b
DB
CGADisplay
; 0110b, 0111b
DB
EGAColorDisplay
; 1000b, 1001b
DB
MDADisplay
; 1010b, 1011b
DCCtable
DB
0
,
0
; translate table for INT 10h func 1Ah
DB
MDA
,
MDADisplay
DB
CGA
,
CGADisplay
DB
0
,
0
DB
EGA
,
EGAColorDisplay
DB
EGA
,
MDADisplay
DB
0
,
0
DB
VGA
,
PS2MonoDisplay
DB
VGA
,
PS2ColorDisplay
DB
0
,
0
DB
MCGA
,
EGAColorDisplay
DB
MCGA
,
PS2MonoDisplay
DB
MCGA
,
PS2ColorDisplay
TestSequence
DB
TRUE
; this list of flags and addresses
DW
FindPS2
; determines the order in which this
; program looks for the various
EGAflag
DB
?
; subsystems
DW
FindEGA
CGAflag
DB
?
DW
FindCGA
Monoflag
DB
?
DW
FindMono
NumberOfTests
EQU
(
$
-
TestSequence
)
/
3
PUBLIC
VL_VideoID
VL_VideoID
PROC
push
bp
; preserve caller registers
mov
bp
,
sp
push
ds
push
si
push
di
push
cs
pop
ds
ASSUME
DS
:
@
Code
; initialize the data structure that will contain the results
lea
di
,
Results
; DS:DI -> start of data structure
mov
Device0
,
0
; zero these variables
mov
Device1
,
0
; look for the various subsystems using the subroutines whose addresses are
; tabulated in TestSequence; each subroutine sets flags in TestSequence
; to indicate whether subsequent subroutines need to be called
mov
byte
ptr
CGAflag
,
TRUE
mov
byte
ptr
EGAflag
,
TRUE
mov
byte
ptr
Monoflag
,
TRUE
mov
cx
,
NumberOfTests
mov
si
,
offset
TestSequence
@@
L01
:
lodsb
; AL := flag
test
al
,
al
lodsw
; AX := subroutine address
jz
@@
L02
; skip subroutine if flag is false
push
si
push
cx
call
ax
; call subroutine to detect subsystem
pop
cx
pop
si
@@
L02
:
loop
@@
L01
; determine which subsystem is active
call
FindActive
mov
al
,
Results
.
Video0Type
mov
ah
,
0
; was: Results.Display0Type
pop
di
; restore caller registers and return
pop
si
pop
ds
mov
sp
,
bp
pop
bp
ret
VL_VideoID
ENDP
;
; FindPS2
;
; This subroutine uses INT 10H function 1Ah to determine the video BIOS
; Display Combination Code (DCC) for each video subsystem present.
;
FindPS2
PROC
near
mov
ax
,
1
A00h
int
10
h
; call video BIOS for info
cmp
al
,
1
Ah
jne
@@
L13
; exit if function not supported (i.e.,
; no MCGA or VGA in system)
; convert BIOS DCCs into specific subsystems & displays
mov
cx
,
bx
xor
bh
,
bh
; BX := DCC for active subsystem
or
ch
,
ch
jz
@@
L11
; jump if only one subsystem present
mov
bl
,
ch
; BX := inactive DCC
add
bx
,
bx
mov
ax
,
[
bx
+
offset
DCCtable
]
mov
Device1
,
ax
mov
bl
,
cl
xor
bh
,
bh
; BX := active DCC
@@
L11
:
add
bx
,
bx
mov
ax
,
[
bx
+
offset
DCCtable
]
mov
Device0
,
ax
; reset flags for subsystems that have been ruled out
mov
byte
ptr
CGAflag
,
FALSE
mov
byte
ptr
EGAflag
,
FALSE
mov
byte
ptr
Monoflag
,
FALSE
lea
bx
,
Video0Type
[di]
; if the BIOS reported an MDA ...
cmp
byte
ptr
[bx],
MDA
je
@@
L12
lea
bx
,
Video1Type
[di]
cmp
byte
ptr
[bx],
MDA
jne
@@
L13
@@
L12
:
mov
word
ptr
[bx],
0
; ... Hercules can't be ruled out
mov
byte
ptr
Monoflag
,
TRUE
@@
L13
:
ret
FindPS2
ENDP
;
; FindEGA
;
; Look for an EGA. This is done by making a call to an EGA BIOS function
; which doesn't exist in the default (MDA, CGA) BIOS.
FindEGA
PROC
near
; Caller: AH = flags
; Returns: AH = flags
; Video0Type and
; Display0Type updated
mov
bl
,
10
h
; BL := 10h (return EGA info)
mov
ah
,
12
h
; AH := INT 10H function number
int
10
h
; call EGA BIOS for info
; if EGA BIOS is present,
; BL <> 10H
; CL = switch setting
cmp
bl
,
10
h
je
@@
L22
; jump if EGA BIOS not present
mov
al
,
cl
shr
al
,
1
; AL := switches/2
mov
bx
,
offset
EGADisplays
xlat
; determine display type from switches
mov
ah
,
al
; AH := display type
mov
al
,
EGA
; AL := subystem type
call
FoundDevice
cmp
ah
,
MDADisplay
je
@@
L21
; jump if EGA has a monochrome display
mov
CGAflag
,
FALSE
; no CGA if EGA has color display
jmp
short
@@
L22
@@
L21
:
mov
Monoflag
,
FALSE
; EGA has a mono display, so MDA and
; Hercules are ruled out
@@
L22
:
ret
FindEGA
ENDP
;
; FindCGA
;
; This is done by looking for the CGA's 6845 CRTC at I/O port 3D4H.
;
FindCGA
PROC
near
; Returns: VIDstruct updated
mov
dx
,
3
D4h
; DX := CRTC address port
call
Find6845
jc
@@
L31
; jump if not present
mov
al
,
CGA
mov
ah
,
CGADisplay
call
FoundDevice
@@
L31
:
ret
FindCGA
ENDP
;
; FindMono
;
; This is done by looking for the MDA's 6845 CRTC at I/O port 3B4H. If
; a 6845 is found, the subroutine distinguishes between an MDA
; and a Hercules adapter by monitoring bit 7 of the CRT Status byte.
; This bit changes on Hercules adapters but does not change on an MDA.
;
; The various Hercules adapters are identified by bits 4 through 6 of
; the CRT Status value:
;
; 000b = HGC
; 001b = HGC+
; 101b = InColor card
;
FindMono
PROC
near
; Returns: VIDstruct updated
mov
dx
,
3
B4h
; DX := CRTC address port
call
Find6845
jc
@@
L44
; jump if not present
mov
dl
,
0
BAh
; DX := 3BAh (status port)
in
al
,
dx
and
al
,
80
h
mov
ah
,
al
; AH := bit 7 (vertical sync on HGC)
mov
cx
,
8000
h
; do this 32768 times
@@
L41
:
in
al
,
dx
and
al
,
80
h
; isolate bit 7
cmp
ah
,
al
loope
@@
L41
; wait for bit 7 to change
jne
@@
L42
; if bit 7 changed, it's a Hercules
mov
al
,
MDA
; if bit 7 didn't change, it's an MDA
mov
ah
,
MDADisplay
call
FoundDevice
jmp
short
@@
L44
@@
L42
:
in
al
,
dx
mov
dl
,
al
; DL := value from status port
and
dl
,
01110000
b
; mask bits 4 thru 6
mov
ah
,
MDADisplay
; assume it's a monochrome display
mov
al
,
HGCPlus
; look for an HGC+
cmp
dl
,
00010000
b
je
@@
L43
; jump if it's an HGC+
mov
al
,
HGC
; look for an InColor card or HGC
cmp
dl
,
01010000
b
jne
@@
L43
; jump if it's not an InColor card
mov
al
,
InColor
; it's an InColor card
mov
ah
,
EGAColorDisplay
@@
L43
:
call
FoundDevice
@@
L44
:
ret
FindMono
ENDP
;
; Find6845
;
; This routine detects the presence of the CRTC on a MDA, CGA or HGC.
; The technique is to write and read register 0Fh of the chip (cursor
; low). If the same value is read as written, assume the chip is
; present at the specified port addr.
;
Find6845
PROC
near
; Caller: DX = port addr
; Returns: cf set if not present
mov
al
,
0
Fh
out
dx
,
al
; select 6845 reg 0Fh (Cursor Low)
inc
dx
in
al
,
dx
; AL := current Cursor Low value
mov
ah
,
al
; preserve in AH
mov
al
,
66
h
; AL := arbitrary value
out
dx
,
al
; try to write to 6845
mov
cx
,
100
h
@@
L51
:
loop
@@
L51
; wait for 6845 to respond
in
al
,
dx
xchg
ah
,
al
; AH := returned value
; AL := original value
out
dx
,
al
; restore original value
cmp
ah
,
66
h
; test whether 6845 responded
je
@@
L52
; jump if it did (cf is reset)
stc
; set carry flag if no 6845 present
@@
L52
:
ret
Find6845
ENDP
;
; FindActive
;
; This subroutine stores the currently active device as Device0. The
; current video mode determines which subsystem is active.
;
FindActive
PROC
near
cmp
word
ptr
Device1
,
0
je
@@
L63
; exit if only one subsystem
cmp
Video0Type
[di],
4
; exit if MCGA or VGA present
jge
@@
L63
; (INT 10H function 1AH
cmp
Video1Type
[di],
4
; already did the work)
jge
@@
L63
mov
ah
,
0
Fh
int
10
h
; AL := current BIOS video mode
and
al
,
7
cmp
al
,
7
; jump if monochrome
je
@@
L61
; (mode 7 or 0Fh)
cmp
Display0Type
[di],
MDADisplay
jne
@@
L63
; exit if Display0 is color
jmp
short
@@
L62
@@
L61
:
cmp
Display0Type
[di],
MDADisplay
je
@@
L63
; exit if Display0 is monochrome
@@
L62
:
mov
ax
,
Device0
; make Device0 currently active
xchg
ax
,
Device1
mov
Device0
,
ax
@@
L63
:
ret
FindActive
ENDP
;
; FoundDevice
;
; This routine updates the list of subsystems.
;
FoundDevice
PROC
near
; Caller: AH = display #
; AL = subsystem #
; Destroys: BX
lea
bx
,
Video0Type
[di]
cmp
byte
ptr
[bx],
0
je
@@
L71
; jump if 1st subsystem
lea
bx
,
Video1Type
[di]
; must be 2nd subsystem
@@
L71
:
mov
[bx],
ax
; update list entry
ret
FoundDevice
ENDP
IDEAL
END
src/wl_main.c
View file @
55edef7f
...
@@ -686,29 +686,13 @@ void SignonScreen (void) // VGA version
...
@@ -686,29 +686,13 @@ void SignonScreen (void) // VGA version
{
{
unsigned
segstart
,
seglength
;
unsigned
segstart
,
seglength
;
VL_SetVGAPlaneMode
();
VL_TestPaletteSet
();
VL_SetPalette
(
&
gamepal
);
VL_SetPalette
(
&
gamepal
);
if
(
!
virtualreality
)
if
(
!
virtualreality
)
{
{
VW_SetScreen
(
0x8000
,
0
);
VL_MungePic
(
&
introscn
,
320
,
200
);
VL_MungePic
(
&
introscn
,
320
,
200
);
VL_MemToScreen
(
&
introscn
,
320
,
200
,
0
,
0
);
VL_MemToScreen
(
&
introscn
,
320
,
200
,
0
,
0
);
VW_SetScreen
(
0
,
0
);
}
}
//
// reclaim the memory from the linked in signon screen
//
segstart
=
FP_SEG
(
&
introscn
);
seglength
=
64000
/
16
;
if
(
FP_OFF
(
&
introscn
))
{
segstart
++
;
seglength
--
;
}
MML_UseSpace
(
segstart
,
seglength
);
}
}
...
...
src/wl_menu.c
View file @
55edef7f
...
@@ -625,18 +625,6 @@ void CP_ReadThis(void)
...
@@ -625,18 +625,6 @@ void CP_ReadThis(void)
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
void
BossKey
(
void
)
void
BossKey
(
void
)
{
{
SD_MusicOff
();
_AX
=
3
;
geninterrupt
(
0x10
);
printf
(
"C>"
);
while
(
!
Keyboard
[
sc_Escape
])
IN_ClearKeysDown
();
SD_MusicOn
();
VL_SetVGAPlaneMode
();
VL_TestPaletteSet
();
VL_SetPalette
(
&
gamepal
);
LoadLatchMem
();
}
}
#endif
#endif
#endif
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment