OSDN Git Service

updated copyleft and need to test and fix newer version of open watcom
[proj16/16.git] / src / lib / 16_sd.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2022 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
3  *\r
4  * This file is part of Project 16.\r
5  *\r
6  * Project 16 is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Project 16 is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
19  * Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  */\r
22 \r
23 //\r
24 //      ID Engine\r
25 //      ID_SD.c - Sound Manager for Wolfenstein 3D\r
26 //      v1.2w\r
27 //      By Jason Blochowiak\r
28 //      Open Watcom port by sparky4\r
29 //\r
30 \r
31 //\r
32 //      This module handles dealing with generating sound on the appropriate\r
33 //              hardware\r
34 //\r
35 //      Depends on: User Mgr (for parm checking)\r
36 //\r
37 //      Globals:\r
38 //              For User Mgr:\r
39 //                      SoundSourcePresent - Sound Source thingie present?\r
40 //                      SoundBlasterPresent - SoundBlaster card present?\r
41 //                      AdLibPresent - AdLib card present?\r
42 //                      SoundMode - What device is used for sound effects\r
43 //                              (Use SM_SetSoundMode() to set)\r
44 //                      MusicMode - What device is used for music\r
45 //                              (Use SM_SetMusicMode() to set)\r
46 //                      DigiMode - What device is used for digitized sound effects\r
47 //                              (Use SM_SetDigiDevice() to set)\r
48 //\r
49 //              For Cache Mgr:\r
50 //                      NeedsDigitized - load digitized sounds?\r
51 //                      NeedsMusic - load music?\r
52 //\r
53 \r
54 #pragma hdrstop         // Wierdo thing with MUSE\r
55 \r
56 #include <dos.h>\r
57 \r
58 #ifndef _MUSE_      // Will be defined in ID_Types.h\r
59 #include "src/lib/16_sd.h"\r
60 #else\r
61 #include "src/lib/16_head.h"\r
62 #endif\r
63 #pragma hdrstop\r
64 #pragma warn    -pia\r
65 \r
66 #define SDL_SoundFinished()     {SoundNumber = SoundPriority = 0;}\r
67 \r
68 // Macros for AdLib stuff\r
69 #define selreg(n)       outportb(alFMAddr,n)\r
70 #define writereg(n)     outportb(alFMData,n)\r
71 #define readstat()      inportb(alFMStatus)\r
72 \r
73 //      Imports from ID_SD_A.ASM\r
74 /*extern*/      void                    SDL_SetDS(void);\r
75 /*extern*/      void interrupt  SDL_t0ExtremeAsmService(void);//,\r
76 //                                      SDL_t0FastAsmService(void),\r
77 //                                      SDL_t0SlowAsmService(void);\r
78         void                    SDL_IndicatePC(boolean on),\r
79                                         SDL_DigitizedDoneInIRQ();\r
80 \r
81 //      Global variables\r
82         boolean         AdLibPresent,\r
83                                 NeedsDigitized,NeedsMusic,\r
84                                 SoundPositioned;\r
85         SDMode          SoundMode;\r
86         SMMode          MusicMode;\r
87         SDSMode         DigiMode;\r
88         dword   TimeCount;\r
89         word            HackCount;\r
90         word            *SoundTable;    // Really * _seg *SoundTable, but that don't work\r
91         boolean         ssIsTandy;\r
92         int                     DigiMap[LASTSOUND];\r
93 \r
94 //      Internal variables\r
95 static  boolean                 SD_Started;\r
96                 boolean                 nextsoundpos;\r
97                 word/*boolean_+*/                       TimerDone;\r
98                 word                    TimerVal,TimerDelay10,TimerDelay25,TimerDelay100;\r
99                 dword           TimerDivisor,TimerCount;\r
100 static  char                    *ParmStrings[] =\r
101                                                 {\r
102                                                         "noal",\r
103                                                         nil\r
104                                                 };\r
105 static  void                    (*SoundUserHook)(void);\r
106                 soundnames              SoundNumber,DigiNumber;\r
107                 word                    SoundPriority,DigiPriority;\r
108                 int                             LeftPosition,RightPosition;\r
109                 void interrupt  (*t0OldService)(void);\r
110                 long                    LocalTime;\r
111                 word                    TimerRate;\r
112 \r
113                 word                    NumDigi,DigiLeft,DigiPage;\r
114                 word                    _seg *DigiList;\r
115                 word                    DigiLastStart,DigiLastEnd;\r
116                 boolean                 DigiPlaying;\r
117 static  boolean                 DigiMissed,DigiLastSegment;\r
118 static  memptr                  DigiNextAddr;\r
119 static  word                    DigiNextLen;\r
120 \r
121 //      PC Sound variables\r
122                 volatile byte   pcLastSample,far *pcSound;\r
123                 dword           pcLengthLeft;\r
124                 word                    pcSoundLookup[255];\r
125 \r
126 //      AdLib variables\r
127                 boolean                 alNoCheck;\r
128                 byte                    far *alSound;\r
129                 word                    alBlock;\r
130                 dword           alLengthLeft;\r
131                 dword           alTimeCount;\r
132                 Instrument              alZeroInst;\r
133 \r
134 // This table maps channel numbers to carrier and modulator op cells\r
135 static  byte                    carriers[9] =  { 3, 4, 5,11,12,13,19,20,21},\r
136                                                 modifiers[9] = { 0, 1, 2, 8, 9,10,16,17,18},\r
137 // This table maps percussive voice numbers to op cells\r
138                                                 pcarriers[5] = {19,0xff,0xff,0xff,0xff},\r
139                                                 pmodifiers[5] = {16,17,18,20,21};\r
140 \r
141 //      Sequencer variables\r
142                 boolean                 sqActive;\r
143 static  word                    alFXReg;\r
144 static  ActiveTrack             *tracks[sqMaxTracks];//,\r
145 //--                                            mytracks[sqMaxTracks];\r
146 //--static      word                    sqMode,sqFadeStep;\r
147                 word                    far *sqHack,far *sqHackPtr,sqHackLen,sqHackSeqLen;\r
148                 long                    sqHackTime;\r
149 \r
150 //      Internal routines\r
151                 void                    SDL_DigitizedDone(void);\r
152 \r
153 //Assembly functions\r
154 boolean         alNoIRQ;\r
155 \r
156 int count_time=0;\r
157 int count_fx=0;\r
158 int extreme=0;\r
159 \r
160 void SDL_turnOnPCSpeaker(word timerval)\r
161 {\r
162         __asm {\r
163                 mov     bx,timerval\r
164                 mov     al,0b6h\r
165                 out     43h,al\r
166                 mov     al,bl\r
167                 out     42h,al\r
168                 mov     al,bh\r
169                 out     42h,al\r
170                 in      al,61h\r
171                 or      al,3\r
172                 out     61h,al\r
173         }\r
174 }\r
175 \r
176 void SDL_turnOffPCSpeaker()\r
177 {\r
178         __asm {\r
179                 in      al,61h\r
180                 and     al,0fch\r
181                 out     61h,al\r
182         }\r
183 }\r
184 \r
185 void SDL_setPCSpeaker(byte val)\r
186 {\r
187         __asm {\r
188                 mov     al,val\r
189                 in      al,61h\r
190                 and     al,0fch\r
191                 or      al,ah\r
192                 out     61h,al\r
193         }\r
194 }\r
195 \r
196 void SDL_DoFX()\r
197 {\r
198         if(pcSound)\r
199         {\r
200                 if(*pcSound!=pcLastSample)\r
201                 {\r
202                         pcLastSample=*pcSound;\r
203 \r
204                         if(pcLastSample)\r
205                                 SDL_turnOnPCSpeaker(pcLastSample*60);\r
206                         else\r
207                                 SDL_turnOffPCSpeaker();\r
208                 }\r
209                 pcSound++;\r
210                 pcLengthLeft--;\r
211                 if(!pcLengthLeft)\r
212                 {\r
213                         pcSound=0;\r
214                         SoundNumber=(soundnames)0;\r
215                         SoundPriority=0;\r
216                         SDL_turnOffPCSpeaker();\r
217                 }\r
218         }\r
219 \r
220         if(alSound && !alNoIRQ)\r
221         {\r
222                 if(*alSound)\r
223                 {\r
224                         alOut/*InIRQ*/(alFreqL,*alSound);\r
225                         alOut/*InIRQ*/(alFreqH,alBlock);\r
226                 }\r
227                 else alOut/*InIRQ*/(alFreqH,0);\r
228                 alSound++;\r
229                 alLengthLeft--;\r
230                 if(!alLengthLeft)\r
231                 {\r
232                         alSound=0;\r
233                         SoundNumber=(soundnames)0;\r
234                         SoundPriority=0;\r
235                         alOut/*InIRQ*/(alFreqH,0);\r
236                 }\r
237         }\r
238 \r
239 }\r
240 \r
241 void SDL_DoFast()\r
242 {\r
243         count_fx++;\r
244         if(count_fx>=5)\r
245         {\r
246                 count_fx=0;\r
247 \r
248                 SDL_DoFX();\r
249 \r
250                 count_time++;\r
251                 if(count_time>=2)\r
252                 {\r
253                         TimeCount++;\r
254                         count_time=0;\r
255                 }\r
256         }\r
257 \r
258         if(sqActive && !alNoIRQ)\r
259         {\r
260                 if(sqHackLen)\r
261                 {\r
262                         do\r
263                         {\r
264                                 if(sqHackTime>alTimeCount) break;\r
265                                 sqHackTime=alTimeCount+*(sqHackPtr+1);\r
266                                 alOut/*InIRQ*/(*(byte *)sqHackPtr,*(((byte *)sqHackPtr)+1));\r
267                                 sqHackPtr+=2;\r
268                                 sqHackLen-=4;\r
269                         }\r
270                         while(sqHackLen);\r
271                 }\r
272                 alTimeCount++;\r
273                 if(!sqHackLen)\r
274                 {\r
275                         sqHackPtr=sqHack;\r
276                         sqHackLen=sqHackSeqLen;\r
277                         alTimeCount=0;\r
278                         sqHackTime=0;\r
279                 }\r
280         }\r
281 \r
282 //SS    if(ssSample)\r
283 //SS    {\r
284 //SS            if(!(inp(ssStatus)&0x40))\r
285 //SS            {\r
286 //SS                    outp(ssData,*ssSample++);\r
287 //SS                    outp(ssControl,ssOff);\r
288 //SS                    __asm push ax\r
289 //SS                    __asm pop ax\r
290 //SS                    outp(ssControl,ssOn);\r
291 //SS                    __asm push ax\r
292 //SS                    __asm pop ax\r
293 //SS                    ssLengthLeft--;\r
294 //SS                    if(!ssLengthLeft)\r
295 //SS                    {\r
296 //SS                            ssSample=0;\r
297 //SS                            SDL_DigitizedDoneInIRQ();\r
298 //SS                    }\r
299 //SS            }\r
300 //SS    }\r
301 \r
302         TimerCount+=TimerDivisor;\r
303         if(*((word *)&TimerCount+1))\r
304         {\r
305                 *((word *)&TimerCount+1)=0;\r
306                 t0OldService();\r
307         }\r
308         else\r
309         {\r
310                 outp(0x20,0x20);\r
311         }\r
312 }\r
313 \r
314 // Timer 0 ISR for 700Hz interrupts\r
315 void interrupt SDL_t0FastAsmService(void)\r
316 {\r
317         SDL_DoFast();\r
318 }\r
319 \r
320 // Timer 0 ISR for 140Hz interrupts\r
321 void interrupt SDL_t0SlowAsmService(void)\r
322 {\r
323         count_time++;\r
324         if(count_time>=2)\r
325         {\r
326                 TimeCount++;\r
327                 count_time=0;\r
328         }\r
329 \r
330         SDL_DoFX();\r
331 \r
332         TimerCount+=TimerDivisor;\r
333         if(*((word *)&TimerCount+1))\r
334         {\r
335                 *((word *)&TimerCount+1)=0;\r
336                 t0OldService();\r
337         }\r
338         else\r
339                 outp(0x20,0x20);\r
340 }\r
341 \r
342 \r
343 ///////////////////////////////////////////////////////////////////////////\r
344 //\r
345 //      SDL_SetTimer0() - Sets system timer 0 to the specified speed\r
346 //\r
347 ///////////////////////////////////////////////////////////////////////////\r
348 #pragma argsused\r
349 static void\r
350 SDL_SetTimer0(word speed)\r
351 {\r
352 #ifndef TPROF   // If using Borland's profiling, don't screw with the timer\r
353 asm     pushf\r
354 asm     cli\r
355 \r
356         outportb(0x43,0x36);                            // Change timer 0\r
357         outportb(0x40,speed);\r
358         outportb(0x40,speed >> 8);\r
359         // Kludge to handle special case for digitized PC sounds\r
360         if (TimerDivisor == (1192030 / (TickBase * 100)))\r
361                 TimerDivisor = (1192030 / (TickBase * 10));\r
362         else\r
363                 TimerDivisor = speed;\r
364 \r
365 asm     popf\r
366 #else\r
367         TimerDivisor = 0x10000;\r
368 #endif\r
369 }\r
370 \r
371 ///////////////////////////////////////////////////////////////////////////\r
372 //\r
373 //      SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of\r
374 //              interrupts generated by system timer 0 per second\r
375 //\r
376 ///////////////////////////////////////////////////////////////////////////\r
377 static void\r
378 SDL_SetIntsPerSec(word ints)\r
379 {\r
380         TimerRate = ints;\r
381         SDL_SetTimer0(1192030 / ints);\r
382 }\r
383 \r
384 #ifndef SD_USECATA3DSETTIMERSPEED\r
385 static void\r
386 SDL_SetTimerSpeed(void)\r
387 {\r
388         word    rate;\r
389         void interrupt  (*isr)(void);\r
390 \r
391         if ((DigiMode == sds_PC) && DigiPlaying)\r
392         {\r
393                 rate = TickBase * 100;\r
394                 isr = SDL_t0ExtremeAsmService;\r
395         }\r
396         else if\r
397         (\r
398                 (MusicMode == smm_AdLib)\r
399         ||      ((DigiMode == sds_SoundSource) && DigiPlaying)\r
400         )\r
401         {\r
402                 rate = TickBase * 10;\r
403                 isr = SDL_t0FastAsmService;\r
404         }\r
405         else\r
406         {\r
407                 rate = TickBase * 2;\r
408                 isr = SDL_t0SlowAsmService;\r
409         }\r
410 \r
411         if (rate != TimerRate)\r
412         {\r
413                 setvect(8,isr);\r
414                 SDL_SetIntsPerSec(rate);\r
415                 TimerRate = rate;\r
416         }\r
417 }\r
418 #else\r
419 static void\r
420 SDL_SetTimerSpeed(void)\r
421 {\r
422         word    rate;\r
423 \r
424         if (MusicMode == smm_AdLib)\r
425                 rate = TickBase * 8;\r
426         else\r
427                 rate = TickBase * 2;\r
428         SDL_SetIntsPerSec(rate);\r
429 }\r
430 #endif\r
431 \r
432 ///////////////////////////////////////////////////////////////////////////\r
433 //\r
434 //      SDL_TimingService() - Used by SDL_InitDelay() to determine a timing\r
435 //              value for the current system that we're running on\r
436 //\r
437 ///////////////////////////////////////////////////////////////////////////\r
438 //static void interrupt\r
439 void interrupt\r
440 SDL_TimingService(void)\r
441 {\r
442         //TimerVal = _CX;\r
443         __asm {\r
444                 mov TimerVal,cx\r
445         }\r
446         TimerDone = 1;\r
447 \r
448         outportb(0x20,0x20);                            // Ack interrupt\r
449 }\r
450 #ifdef SD_USECATA3DSETTIMERSPEED\r
451 ///////////////////////////////////////////////////////////////////////////\r
452 //\r
453 //      SDL_InitDelay() - Sets up TimerDelay's for SDL_Delay()\r
454 //\r
455 ///////////////////////////////////////////////////////////////////////////\r
456 static void\r
457 SDL_InitDelay(void)\r
458 {\r
459         int             i;\r
460         word    timer;\r
461 \r
462 //++++  setvect(8,SDL_TimingService);           // Set to my timer 0 ISR\r
463 \r
464         SDL_SetIntsPerSec(1000);                        // Time 1ms\r
465 \r
466         for (i = 0,timer = 0;i < 10;i++)        // Do timing test 10 times\r
467         {\r
468                 __asm {\r
469                         xor             dx,dx                                   // Zero DX\r
470                         mov             cx,0xffff                               // Put starting value in CX\r
471                         mov             [TimerDone],cx                  // TimerDone = false - 1\r
472 #ifdef __BORLANDC__\r
473                 }\r
474 #endif\r
475 startloop:\r
476 #ifdef __BORLANDC__\r
477                 __asm {\r
478 #endif\r
479                         or              [TimerDone],0\r
480                         jnz             startloop                               // Make sure we're at the start\r
481 #ifdef __BORLANDC__\r
482                 }\r
483 #endif\r
484 loop_:\r
485 #ifdef __BORLANDC__\r
486                 __asm {\r
487 #endif\r
488                         test    [TimerDone],1                   // See if TimerDone flag got hit\r
489                         jnz             done                                    // Yep - drop out of the loop\r
490                         loop    loop_\r
491 #ifdef __BORLANDC__\r
492                 }\r
493 #endif\r
494 done:\r
495 #ifdef __WATCOMC__\r
496         }\r
497 #endif\r
498 \r
499                 if (0xffff - TimerVal > timer)\r
500                         timer = 0xffff - TimerVal;\r
501         }\r
502         timer += timer / 2;                                     // Use some slop\r
503         TimerDelay10 =  timer / (1000 / 10);\r
504         TimerDelay25 =  timer / (1000 / 25);\r
505         TimerDelay100 = timer / (1000 / 100);\r
506 \r
507         SDL_SetTimer0(0);                                       // Reset timer 0\r
508 \r
509         setvect(8,t0OldService);                        // Set back to old ISR\r
510 }\r
511 #endif\r
512 ///////////////////////////////////////////////////////////////////////////\r
513 //\r
514 //      SDL_Delay() - Delays the specified amount of time\r
515 //\r
516 ///////////////////////////////////////////////////////////////////////////\r
517 static void\r
518 SDL_Delay(word delay)\r
519 {\r
520         if (!delay)\r
521                 return;\r
522 \r
523         __asm {\r
524                 mov             cx,[delay]\r
525 #ifdef __BORLANDC__\r
526         }\r
527 #endif\r
528 loop_:\r
529 #ifdef __BORLANDC__\r
530         __asm {\r
531 #endif\r
532                 test    [TimerDone],0   // Useless code - just for timing equivilency\r
533                 jnz             done\r
534                 loop    loop_\r
535 #ifdef __BORLANDC__\r
536         }\r
537 #endif\r
538 done:\r
539 #ifdef __WATCOMC__\r
540         }\r
541 #endif\r
542 }\r
543 \r
544 //\r
545 //      PC Sound code\r
546 //\r
547 \r
548 ///////////////////////////////////////////////////////////////////////////\r
549 //\r
550 //      SDL_PCPlaySample() - Plays the specified sample on the PC speaker\r
551 //\r
552 ///////////////////////////////////////////////////////////////////////////\r
553 #ifdef  _MUSE_\r
554 void\r
555 #else\r
556 static void\r
557 #endif\r
558 SDL_PCPlaySample(byte huge *data,dword len)\r
559 {\r
560 asm     pushf\r
561 asm     cli\r
562 \r
563         SDL_IndicatePC(true);\r
564 \r
565         pcLengthLeft = len;\r
566         pcSound = (volatile byte far *)data;\r
567 \r
568 asm     popf\r
569 }\r
570 \r
571 ///////////////////////////////////////////////////////////////////////////\r
572 //\r
573 //      SDL_PCStopSample() - Stops a sample playing on the PC speaker\r
574 //\r
575 ///////////////////////////////////////////////////////////////////////////\r
576 #ifdef  _MUSE_\r
577 void\r
578 #else\r
579 static void\r
580 #endif\r
581 SDL_PCStopSample(void)\r
582 {\r
583 asm     pushf\r
584 asm     cli\r
585 \r
586         /*(long)*/pcSound = 0;\r
587 \r
588         SDL_IndicatePC(false);\r
589 \r
590 asm     in      al,0x61                 // Turn the speaker off\r
591 asm     and     al,0xfd                 // ~2\r
592 asm     out     0x61,al\r
593 \r
594 asm     popf\r
595 }\r
596 \r
597 ///////////////////////////////////////////////////////////////////////////\r
598 //\r
599 //      SDL_PCPlaySound() - Plays the specified sound on the PC speaker\r
600 //\r
601 ///////////////////////////////////////////////////////////////////////////\r
602 #ifdef  _MUSE_\r
603 void\r
604 #else\r
605 static void\r
606 #endif\r
607 SDL_PCPlaySound(PCSound far *sound)\r
608 {\r
609 asm     pushf\r
610 asm     cli\r
611 \r
612         pcLastSample = -1;\r
613         pcLengthLeft = sound->common.length;\r
614         pcSound = sound->data;\r
615 \r
616 asm     popf\r
617 }\r
618 \r
619 ///////////////////////////////////////////////////////////////////////////\r
620 //\r
621 //      SDL_PCStopSound() - Stops the current sound playing on the PC Speaker\r
622 //\r
623 ///////////////////////////////////////////////////////////////////////////\r
624 #ifdef  _MUSE_\r
625 void\r
626 #else\r
627 static void\r
628 #endif\r
629 SDL_PCStopSound(void)\r
630 {\r
631 asm     pushf\r
632 asm     cli\r
633 \r
634         /*(long)*/pcSound = 0;\r
635 \r
636 asm     in      al,0x61                 // Turn the speaker off\r
637 asm     and     al,0xfd                 // ~2\r
638 asm     out     0x61,al\r
639 \r
640 asm     popf\r
641 }\r
642 \r
643 ///////////////////////////////////////////////////////////////////////////\r
644 //\r
645 //      SDL_PCService() - Handles playing the next sample in a PC sound\r
646 //\r
647 ///////////////////////////////////////////////////////////////////////////\r
648 static void\r
649 SDL_PCService(void)\r
650 {\r
651         byte    s;\r
652         word    t;\r
653 \r
654         if (pcSound)\r
655         {\r
656                 s = *pcSound++;\r
657                 if (s != pcLastSample)\r
658                 {\r
659                 asm     pushf\r
660                 asm     cli\r
661 \r
662                         pcLastSample = s;\r
663                         if (s)                                  // We have a frequency!\r
664                         {\r
665                                 t = pcSoundLookup[s];\r
666                         asm     mov     bx,[t]\r
667 \r
668                         asm     mov     al,0xb6                 // Write to channel 2 (speaker) timer\r
669                         asm     out     43h,al\r
670                         asm     mov     al,bl\r
671                         asm     out     42h,al                  // Low byte\r
672                         asm     mov     al,bh\r
673                         asm     out     42h,al                  // High byte\r
674 \r
675                         asm     in      al,0x61                 // Turn the speaker & gate on\r
676                         asm     or      al,3\r
677                         asm     out     0x61,al\r
678                         }\r
679                         else                                    // Time for some silence\r
680                         {\r
681                         asm     in      al,0x61                 // Turn the speaker & gate off\r
682                         asm     and     al,0xfc                 // ~3\r
683                         asm     out     0x61,al\r
684                         }\r
685 \r
686                 asm     popf\r
687                 }\r
688 \r
689                 if (!(--pcLengthLeft))\r
690                 {\r
691                         SDL_PCStopSound();\r
692                         SDL_SoundFinished();\r
693                 }\r
694         }\r
695 }\r
696 \r
697 ///////////////////////////////////////////////////////////////////////////\r
698 //\r
699 //      SDL_ShutPC() - Turns off the pc speaker\r
700 //\r
701 ///////////////////////////////////////////////////////////////////////////\r
702 static void\r
703 SDL_ShutPC(void)\r
704 {\r
705 asm     pushf\r
706 asm     cli\r
707 \r
708         pcSound = 0;\r
709 \r
710 asm     in      al,0x61                 // Turn the speaker & gate off\r
711 asm     and     al,0xfc                 // ~3\r
712 asm     out     0x61,al\r
713 \r
714 asm     popf\r
715 }\r
716 \r
717 //\r
718 //      Stuff for digitized sounds\r
719 //\r
720 memptr\r
721 SDL_LoadDigiSegment(word page, global_game_variables_t *gvar)\r
722 {\r
723         memptr  addr;\r
724 \r
725 #if 0   // for debugging\r
726 asm     mov     dx,STATUS_REGISTER_1\r
727 asm     in      al,dx\r
728 asm     mov     dx,ATR_INDEX\r
729 asm     mov     al,ATR_OVERSCAN\r
730 asm     out     dx,al\r
731 asm     mov     al,10   // bright green\r
732 asm     out     dx,al\r
733 #endif\r
734 \r
735         addr = PM_GetSoundPage(page);\r
736         PM_SetPageLock(gvar->pm.fi.PMSoundStart + page,pml_Locked, gvar);\r
737 \r
738 #if 0   // for debugging\r
739 asm     mov     dx,STATUS_REGISTER_1\r
740 asm     in      al,dx\r
741 asm     mov     dx,ATR_INDEX\r
742 asm     mov     al,ATR_OVERSCAN\r
743 asm     out     dx,al\r
744 asm     mov     al,3    // blue\r
745 asm     out     dx,al\r
746 asm     mov     al,0x20 // normal\r
747 asm     out     dx,al\r
748 #endif\r
749 \r
750         return(addr);\r
751 }\r
752 \r
753 void\r
754 SDL_PlayDigiSegment(memptr addr,word len)\r
755 {\r
756         switch (DigiMode)\r
757         {\r
758         case sds_PC:\r
759         SDL_PCPlaySample(addr,len);\r
760                 break;\r
761 //SS    case sds_SoundSource:\r
762 //SS            SDL_SSPlaySample(addr,len);\r
763 //SS            break;\r
764 //SB    case sds_SoundBlaster:\r
765 //SB            SDL_SBPlaySample(addr,len);\r
766 //SB            break;\r
767         }\r
768 }\r
769 \r
770 void\r
771 SD_StopDigitized(global_game_variables_t *gvar)\r
772 {\r
773         int     i;\r
774 \r
775 asm     pushf\r
776 asm     cli\r
777 \r
778         DigiLeft = 0;\r
779         DigiNextAddr = nil;\r
780         DigiNextLen = 0;\r
781         DigiMissed = false;\r
782         DigiPlaying = false;\r
783         DigiNumber = DigiPriority = 0;\r
784         SoundPositioned = false;\r
785         if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
786                 SDL_SoundFinished();\r
787 \r
788         switch (DigiMode)\r
789         {\r
790         case sds_PC:\r
791                 SDL_PCStopSample();\r
792                 break;\r
793 //SS    case sds_SoundSource:\r
794 //SS            SDL_SSStopSample();\r
795 //SS            break;\r
796 //SB    case sds_SoundBlaster:\r
797 //SB            SDL_SBStopSample();\r
798 //SB            break;\r
799         }\r
800 \r
801 asm     popf\r
802 \r
803         for (i = DigiLastStart;i < DigiLastEnd;i++)\r
804                 PM_SetPageLock(i + gvar->pm.fi.PMSoundStart,pml_Unlocked, gvar);\r
805         DigiLastStart = 1;\r
806         DigiLastEnd = 0;\r
807 }\r
808 \r
809 void\r
810 SD_Poll(global_game_variables_t *gvar)\r
811 {\r
812         if (DigiLeft && !DigiNextAddr)\r
813         {\r
814                 DigiNextLen = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);\r
815                 DigiLeft -= DigiNextLen;\r
816                 if (!DigiLeft)\r
817                         DigiLastSegment = true;\r
818                 DigiNextAddr = SDL_LoadDigiSegment(DigiPage++, gvar);\r
819         }\r
820         if (DigiMissed && DigiNextAddr)\r
821         {\r
822                 SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);\r
823                 DigiNextAddr = nil;\r
824                 DigiMissed = false;\r
825                 if (DigiLastSegment)\r
826                 {\r
827                         DigiPlaying = false;\r
828                         DigiLastSegment = false;\r
829                 }\r
830         }\r
831         SDL_SetTimerSpeed();\r
832 }\r
833 \r
834 void\r
835 SD_SetPosition(int leftpos,int rightpos, global_game_variables_t *gvar)\r
836 {\r
837         if\r
838         (\r
839                 (leftpos < 0)\r
840         ||      (leftpos > 15)\r
841         ||      (rightpos < 0)\r
842         ||      (rightpos > 15)\r
843         ||      ((leftpos == 15) && (rightpos == 15))\r
844         )\r
845                 Quit(gvar, "SD_SetPosition: Illegal position");\r
846 \r
847         switch (DigiMode)\r
848         {\r
849 //SB    case sds_SoundBlaster:\r
850 //SB            SDL_PositionSBP(leftpos,rightpos);\r
851 //SB            break;\r
852         }\r
853 }\r
854 \r
855 void\r
856 SD_PlayDigitized(word which,int leftpos,int rightpos, global_game_variables_t *gvar)\r
857 {\r
858         word    len;\r
859         memptr  addr;\r
860 \r
861         if (!DigiMode)\r
862                 return;\r
863 \r
864         SD_StopDigitized(gvar);\r
865         if (which >= NumDigi)\r
866                 Quit(gvar, "SD_PlayDigitized: bad sound number");\r
867 \r
868         SD_SetPosition(leftpos,rightpos, gvar);\r
869 \r
870         DigiPage = DigiList[(which * 2) + 0];\r
871         DigiLeft = DigiList[(which * 2) + 1];\r
872 \r
873         DigiLastStart = DigiPage;\r
874         DigiLastEnd = DigiPage + ((DigiLeft + (PMPageSize - 1)) / PMPageSize);\r
875 \r
876         len = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);\r
877         addr = SDL_LoadDigiSegment(DigiPage++, gvar);\r
878 \r
879         DigiPlaying = true;\r
880         DigiLastSegment = false;\r
881 \r
882         SDL_PlayDigiSegment(addr,len);\r
883         DigiLeft -= len;\r
884         if (!DigiLeft)\r
885                 DigiLastSegment = true;\r
886 \r
887         SD_Poll(gvar);\r
888 }\r
889 \r
890 void\r
891 SDL_DigitizedDone(void)\r
892 {\r
893         if (DigiNextAddr)\r
894         {\r
895                 SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);\r
896                 DigiNextAddr = nil;\r
897                 DigiMissed = false;\r
898         }\r
899         else\r
900         {\r
901                 if (DigiLastSegment)\r
902                 {\r
903                         DigiPlaying = false;\r
904                         DigiLastSegment = false;\r
905                         if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
906                         {\r
907                                 SDL_SoundFinished();\r
908                         }\r
909                         else\r
910                                 DigiNumber = DigiPriority = 0;\r
911                         SoundPositioned = false;\r
912                 }\r
913                 else\r
914                         DigiMissed = true;\r
915         }\r
916 }\r
917 \r
918 void\r
919 SD_SetDigiDevice(SDSMode mode, global_game_variables_t *gvar)\r
920 {\r
921         boolean devicenotpresent;\r
922 \r
923         if (mode == DigiMode)\r
924                 return;\r
925 \r
926         SD_StopDigitized(gvar);\r
927 \r
928         devicenotpresent = false;\r
929 //SBSS  switch (mode)\r
930 //SBSS  {\r
931 //SB    case sds_SoundBlaster:\r
932 //SB            if (!SoundBlasterPresent)\r
933 //SB            {\r
934 //SB                    if (SoundSourcePresent)\r
935 //SB                            mode = sds_SoundSource;\r
936 //SB                    else\r
937 //SB                            devicenotpresent = true;\r
938 //SB            }\r
939 //SB            break;\r
940 //SS    case sds_SoundSource:\r
941 //SS            if (!SoundSourcePresent)\r
942 //SS                    devicenotpresent = true;\r
943 //SS            break;\r
944 //SBSS  }\r
945 \r
946         if (!devicenotpresent)\r
947         {\r
948 //SS            if (DigiMode == sds_SoundSource)\r
949 //SS                    SDL_ShutSS();\r
950 \r
951                 DigiMode = mode;\r
952 \r
953 //SS            if (mode == sds_SoundSource)\r
954 //SS                    SDL_StartSS();\r
955 \r
956                 SDL_SetTimerSpeed();\r
957         }\r
958 }\r
959 \r
960 void\r
961 SDL_SetupDigi(global_game_variables_t *gvar)\r
962 {\r
963         memptr  list;\r
964         word    far *p,\r
965                         pg;\r
966         int             i;\r
967 \r
968         PM_UnlockMainMem(gvar);\r
969         MM_GetPtr(&list,PMPageSize, gvar);\r
970         PM_CheckMainMem(gvar);\r
971         p = (word far *)MK_FP(PM_GetPage(gvar->pm.fi.ChunksInFile - 1, gvar),0);\r
972         _fmemcpy((void far *)list,(void far *)p,PMPageSize);\r
973         pg = gvar->pm.fi.PMSoundStart;\r
974         for (i = 0;i < PMPageSize / (sizeof(word) * 2);i++,p += 2)\r
975         {\r
976                 if (pg >= gvar->pm.fi.ChunksInFile - 1)\r
977                         break;\r
978                 pg += (p[1] + (PMPageSize - 1)) / PMPageSize;\r
979         }\r
980         PM_UnlockMainMem(gvar);\r
981         MM_GetPtr(MEMPTRCONV DigiList,i * sizeof(word) * 2, gvar);\r
982         _fmemcpy((void far *)DigiList,(void far *)list,i * sizeof(word) * 2);\r
983         MM_FreePtr(&list, gvar);\r
984         NumDigi = i;\r
985 \r
986         for (i = 0;i < LASTSOUND;i++)\r
987                 DigiMap[i] = -1;\r
988 }\r
989 \r
990 //      AdLib Code\r
991 \r
992 ///////////////////////////////////////////////////////////////////////////\r
993 //\r
994 //      alOut(n,b) - Puts b in AdLib card register n\r
995 //\r
996 ///////////////////////////////////////////////////////////////////////////\r
997 void\r
998 alOut(byte n,byte b)\r
999 {\r
1000 asm     pushf\r
1001 asm     cli\r
1002 \r
1003 asm     mov             dx,0x388\r
1004 asm     mov             al,[n]\r
1005 asm     out             dx,al\r
1006 #if 0\r
1007         SDL_Delay(TimerDelay10);\r
1008 #else\r
1009 asm     in      al, dx\r
1010 asm     in      al, dx\r
1011 asm     in      al, dx\r
1012 asm     in      al, dx\r
1013 asm     in      al, dx\r
1014 asm     in      al, dx\r
1015 #endif\r
1016 \r
1017 asm     mov             dx,0x389\r
1018 asm     mov             al,[b]\r
1019 asm     out             dx,al\r
1020 \r
1021 asm     popf\r
1022 \r
1023 #if 0\r
1024         SDL_Delay(TimerDelay25);\r
1025 #else\r
1026 asm     mov     dx,0x388\r
1027 asm     in      al, dx\r
1028 asm     in      al, dx\r
1029 asm     in      al, dx\r
1030 asm     in      al, dx\r
1031 asm     in      al, dx\r
1032 asm     in      al, dx\r
1033 asm     in      al, dx\r
1034 asm     in      al, dx\r
1035 asm     in      al, dx\r
1036 asm     in      al, dx\r
1037 \r
1038 asm     in      al, dx\r
1039 asm     in      al, dx\r
1040 asm     in      al, dx\r
1041 asm     in      al, dx\r
1042 asm     in      al, dx\r
1043 asm     in      al, dx\r
1044 asm     in      al, dx\r
1045 asm     in      al, dx\r
1046 asm     in      al, dx\r
1047 asm     in      al, dx\r
1048 \r
1049 asm     in      al, dx\r
1050 asm     in      al, dx\r
1051 asm     in      al, dx\r
1052 asm     in      al, dx\r
1053 asm     in      al, dx\r
1054 asm     in      al, dx\r
1055 asm     in      al, dx\r
1056 asm     in      al, dx\r
1057 asm     in      al, dx\r
1058 asm     in      al, dx\r
1059 \r
1060 asm     in      al, dx\r
1061 asm     in      al, dx\r
1062 asm     in      al, dx\r
1063 asm     in      al, dx\r
1064 asm     in      al, dx\r
1065 #endif\r
1066 }\r
1067 \r
1068 //#if 0\r
1069 ///////////////////////////////////////////////////////////////////////////\r
1070 //\r
1071 //      SDL_SetInstrument() - Puts an instrument into a generator\r
1072 //\r
1073 ///////////////////////////////////////////////////////////////////////////\r
1074 //static void\r
1075 void\r
1076 SDL_SetInstrument(int track,int which,Instrument far *inst,boolean percussive)\r
1077 {\r
1078         byte            c,m;\r
1079 \r
1080         if (percussive)\r
1081         {\r
1082                 c = pcarriers[which];\r
1083                 m = pmodifiers[which];\r
1084         }\r
1085         else\r
1086         {\r
1087                 c = carriers[which];\r
1088                 m = modifiers[which];\r
1089         }\r
1090 \r
1091         tracks[track - 1]->inst = *inst;\r
1092         tracks[track - 1]->percussive = percussive;\r
1093 \r
1094         alOut(m + alChar,inst->mChar);\r
1095         alOut(m + alScale,inst->mScale);\r
1096         alOut(m + alAttack,inst->mAttack);\r
1097         alOut(m + alSus,inst->mSus);\r
1098         alOut(m + alWave,inst->mWave);\r
1099 \r
1100         // Most percussive instruments only use one cell\r
1101         if (c != 0xff)\r
1102         {\r
1103                 alOut(c + alChar,inst->cChar);\r
1104                 alOut(c + alScale,inst->cScale);\r
1105                 alOut(c + alAttack,inst->cAttack);\r
1106                 alOut(c + alSus,inst->cSus);\r
1107                 alOut(c + alWave,inst->cWave);\r
1108         }\r
1109 \r
1110         alOut(which + alFeedCon,inst->nConn);   // DEBUG - I think this is right\r
1111 }\r
1112 //#endif\r
1113 \r
1114 ///////////////////////////////////////////////////////////////////////////\r
1115 //\r
1116 //      SDL_ALStopSound() - Turns off any sound effects playing through the\r
1117 //              AdLib card\r
1118 //\r
1119 ///////////////////////////////////////////////////////////////////////////\r
1120 #ifdef  _MUSE_\r
1121 void\r
1122 #else\r
1123 static void\r
1124 #endif\r
1125 SDL_ALStopSound(void)\r
1126 {\r
1127 asm     pushf\r
1128 asm     cli\r
1129 \r
1130         /*(long)*/alSound = 0;\r
1131         alOut(alFreqH + 0,0);\r
1132 \r
1133 asm     popf\r
1134 }\r
1135 \r
1136 static void\r
1137 SDL_AlSetFXInst(Instrument far *inst)\r
1138 {\r
1139         byte            c,m;\r
1140 \r
1141         m = modifiers[0];\r
1142         c = carriers[0];\r
1143         alOut(m + alChar,inst->mChar);\r
1144         alOut(m + alScale,inst->mScale);\r
1145         alOut(m + alAttack,inst->mAttack);\r
1146         alOut(m + alSus,inst->mSus);\r
1147         alOut(m + alWave,inst->mWave);\r
1148         alOut(c + alChar,inst->cChar);\r
1149         alOut(c + alScale,inst->cScale);\r
1150         alOut(c + alAttack,inst->cAttack);\r
1151         alOut(c + alSus,inst->cSus);\r
1152         alOut(c + alWave,inst->cWave);\r
1153 \r
1154         // Note: Switch commenting on these lines for old MUSE compatibility\r
1155 //      alOut(alFeedCon,inst->nConn);\r
1156         alOut(alFeedCon,0);\r
1157 }\r
1158 \r
1159 ///////////////////////////////////////////////////////////////////////////\r
1160 //\r
1161 //      SDL_ALPlaySound() - Plays the specified sound on the AdLib card\r
1162 //\r
1163 ///////////////////////////////////////////////////////////////////////////\r
1164 #ifdef  _MUSE_\r
1165 void\r
1166 #else\r
1167 static void\r
1168 #endif\r
1169 SDL_ALPlaySound(AdLibSound far *sound, global_game_variables_t *gvar)\r
1170 {\r
1171         Instrument      __far *inst;\r
1172         byte            huge *data;\r
1173 \r
1174         SDL_ALStopSound();\r
1175 \r
1176 asm     pushf\r
1177 asm     cli\r
1178 \r
1179         alLengthLeft = sound->common.length;\r
1180         data = sound->data;\r
1181         data++;\r
1182         data--;\r
1183         alSound = (byte far *)data;\r
1184         alBlock = ((sound->block & 7) << 2) | 0x20;\r
1185         inst = &sound->inst;\r
1186 \r
1187         if (!(inst->mSus | inst->cSus))\r
1188         {\r
1189         asm     popf\r
1190                 Quit(gvar, "SDL_ALPlaySound() - Bad instrument");\r
1191         }\r
1192 \r
1193         SDL_AlSetFXInst(&alZeroInst);   // DEBUG\r
1194         SDL_AlSetFXInst(inst);\r
1195 \r
1196 asm     popf\r
1197 }\r
1198 \r
1199 //#if 0\r
1200 ///////////////////////////////////////////////////////////////////////////\r
1201 //\r
1202 //      SDL_ALSoundService() - Plays the next sample out through the AdLib card\r
1203 //\r
1204 ///////////////////////////////////////////////////////////////////////////\r
1205 //static void\r
1206 void\r
1207 SDL_ALSoundService(void)\r
1208 {\r
1209         byte    s;\r
1210 \r
1211         if (alSound)\r
1212         {\r
1213                 s = *alSound++;\r
1214                 if (!s)\r
1215                         alOut(alFreqH + 0,0);\r
1216                 else\r
1217                 {\r
1218                         alOut(alFreqL + 0,s);\r
1219                         alOut(alFreqH + 0,alBlock);\r
1220                 }\r
1221 \r
1222                 if (!(--alLengthLeft))\r
1223                 {\r
1224                         /*(long)*/alSound = 0;\r
1225                         alOut(alFreqH + 0,0);\r
1226                         SDL_SoundFinished();\r
1227                 }\r
1228         }\r
1229 }\r
1230 //#endif\r
1231 \r
1232 #if 0\r
1233 ///////////////////////////////////////////////////////////////////////////\r
1234 //\r
1235 //      SDL_SelectMeasure() - sets up sequencing variables for a given track\r
1236 //\r
1237 ///////////////////////////////////////////////////////////////////////////\r
1238 void\r
1239 SDL_SelectMeasure(ActiveTrack *track)\r
1240 {\r
1241         track->seq = track->moods[track->mood];\r
1242         track->nextevent = 0;\r
1243 }\r
1244 #endif\r
1245 \r
1246 //#if 0\r
1247 void\r
1248 SDL_ALService(void)\r
1249 {\r
1250         byte    a,v;\r
1251         word    w;\r
1252 \r
1253         a=v=0;\r
1254 \r
1255         if (!sqActive)\r
1256                 return;\r
1257 \r
1258         while (sqHackLen && (sqHackTime <= alTimeCount))\r
1259         {\r
1260                 w = *sqHackPtr++;\r
1261                 sqHackTime = alTimeCount + *sqHackPtr++;\r
1262         asm     mov     dx,[w]\r
1263         asm     mov     [a],dl\r
1264         asm     mov     [v],dh\r
1265                 alOut(a,v);\r
1266                 sqHackLen -= 4;\r
1267         }\r
1268         alTimeCount++;\r
1269         if (!sqHackLen)\r
1270         {\r
1271                 sqHackPtr = (word far *)sqHack;\r
1272                 sqHackLen = sqHackSeqLen;\r
1273                 alTimeCount = sqHackTime = 0;\r
1274         }\r
1275 }\r
1276 //#endif\r
1277 \r
1278 ///////////////////////////////////////////////////////////////////////////\r
1279 //\r
1280 //      SDL_ShutAL() - Shuts down the AdLib card for sound effects\r
1281 //\r
1282 ///////////////////////////////////////////////////////////////////////////\r
1283 static void\r
1284 SDL_ShutAL(void)\r
1285 {\r
1286 asm     pushf\r
1287 asm     cli\r
1288 \r
1289         alOut(alEffects,0);\r
1290         alOut(alFreqH + 0,0);\r
1291         SDL_AlSetFXInst(&alZeroInst);\r
1292         alSound = 0;\r
1293 \r
1294 asm     popf\r
1295 }\r
1296 \r
1297 ///////////////////////////////////////////////////////////////////////////\r
1298 //\r
1299 //      SDL_CleanAL() - Totally shuts down the AdLib card\r
1300 //\r
1301 ///////////////////////////////////////////////////////////////////////////\r
1302 static void\r
1303 SDL_CleanAL(void)\r
1304 {\r
1305         int     i;\r
1306 \r
1307 asm     pushf\r
1308 asm     cli\r
1309 \r
1310         alOut(alEffects,0);\r
1311         for (i = 1;i < 0xf5;i++)\r
1312                 alOut(i,0);\r
1313 \r
1314 asm     popf\r
1315 }\r
1316 \r
1317 ///////////////////////////////////////////////////////////////////////////\r
1318 //\r
1319 //      SDL_StartAL() - Starts up the AdLib card for sound effects\r
1320 //\r
1321 ///////////////////////////////////////////////////////////////////////////\r
1322 static void\r
1323 SDL_StartAL(void)\r
1324 {\r
1325         alFXReg = 0;\r
1326         alOut(alEffects,alFXReg);\r
1327         SDL_AlSetFXInst(&alZeroInst);\r
1328 }\r
1329 \r
1330 ///////////////////////////////////////////////////////////////////////////\r
1331 //\r
1332 //      SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster\r
1333 //              emulating an AdLib) present\r
1334 //\r
1335 ///////////////////////////////////////////////////////////////////////////\r
1336 static boolean\r
1337 SDL_DetectAdLib(void)\r
1338 {\r
1339         byte    status1,status2;\r
1340         int             i;\r
1341 \r
1342         alOut(4,0x60);  // Reset T1 & T2\r
1343         alOut(4,0x80);  // Reset IRQ\r
1344         status1 = readstat();\r
1345         alOut(2,0xff);  // Set timer 1\r
1346         alOut(4,0x21);  // Start timer 1\r
1347         SDL_Delay(TimerDelay100);\r
1348 \r
1349 #if 0\r
1350         __asm {\r
1351                 mov     dx,0x388\r
1352                 mov     cx,100\r
1353 #ifdef __BORLANDC__\r
1354         }\r
1355 #endif\r
1356 usecloop:\r
1357 #ifdef __BORLANDC__\r
1358         __asm {\r
1359 #endif\r
1360         in      al,dx\r
1361         loop usecloop\r
1362         }\r
1363 #endif\r
1364 \r
1365         status2 = readstat();\r
1366         alOut(4,0x60);\r
1367         alOut(4,0x80);\r
1368 \r
1369         if (((status1 & 0xe0) == 0x00) && ((status2 & 0xe0) == 0xc0))\r
1370         {\r
1371                 for (i = 1;i <= 0xf5;i++)       // Zero all the registers\r
1372                         alOut(i,0);\r
1373 \r
1374                 alOut(1,0x20);  // Set WSE=1\r
1375                 alOut(8,0);             // Set CSM=0 & SEL=0\r
1376 \r
1377                 return(true);\r
1378         }\r
1379         else\r
1380                 return(false);\r
1381 }\r
1382 \r
1383 ///////////////////////////////////////////////////////////////////////////\r
1384 //\r
1385 //      SDL_t0Service() - My timer 0 ISR which handles the different timings and\r
1386 //              dispatches to whatever other routines are appropriate\r
1387 //\r
1388 ///////////////////////////////////////////////////////////////////////////\r
1389 //static void interrupt\r
1390 void interrupt\r
1391 SDL_t0Service(void)\r
1392 {\r
1393 static  word    count = 1;\r
1394         boolean myackflag = 0;\r
1395 \r
1396 //00#if 0       // for debugging\r
1397 asm     mov     dx,STATUS_REGISTER_1\r
1398 asm     in      al,dx\r
1399 asm     mov     dx,ATR_INDEX\r
1400 asm     mov     al,ATR_OVERSCAN\r
1401 asm     out     dx,al\r
1402 asm     mov     al,4    // red\r
1403 asm     out     dx,al\r
1404 //00#endif\r
1405 \r
1406         HackCount++;\r
1407 \r
1408         if ((MusicMode == smm_AdLib) || (DigiMode == sds_SoundSource))\r
1409         {\r
1410                 SDL_ALService();\r
1411 //SS            SDL_SSService();\r
1412 //              if (!(++count & 7))\r
1413                 if (!(++count % 10))\r
1414                 {\r
1415                         LocalTime++;\r
1416                         TimeCount++;\r
1417                         if (SoundUserHook)\r
1418                                 SoundUserHook();\r
1419                 }\r
1420 //              if (!(count & 3))\r
1421                 if (!(count % 5))\r
1422                 {\r
1423                         switch (SoundMode)\r
1424                         {\r
1425                         case sdm_PC:\r
1426                                 SDL_PCService();\r
1427                                 break;\r
1428                         case sdm_AdLib:\r
1429                                 SDL_ALSoundService();\r
1430                                 break;\r
1431                         }\r
1432                 }\r
1433         }\r
1434         else\r
1435         {\r
1436                 if (!(++count & 1))\r
1437                 {\r
1438                         LocalTime++;\r
1439                         TimeCount++;\r
1440                         if (SoundUserHook)\r
1441                                 SoundUserHook();\r
1442                 }\r
1443                 switch (SoundMode)\r
1444                 {\r
1445                 case sdm_PC:\r
1446                         SDL_PCService();\r
1447                         break;\r
1448                 case sdm_AdLib:\r
1449                         SDL_ALSoundService();\r
1450                         break;\r
1451                 }\r
1452         }\r
1453 \r
1454         __asm {\r
1455                 mov     ax,[WORD PTR TimerCount]\r
1456                 add     ax,[WORD PTR TimerDivisor]\r
1457                 mov     [WORD PTR TimerCount],ax\r
1458                 jnc     myack\r
1459                 jmp end1\r
1460 #ifdef __BORLANDC__\r
1461         }\r
1462 #endif\r
1463 myack:\r
1464 #ifdef __BORLANDC__\r
1465         __asm {\r
1466 #endif\r
1467                 mov     myackflag,1\r
1468 #ifdef __BORLANDC__\r
1469         }\r
1470 #endif\r
1471 end1:\r
1472 #ifdef __WATCOMC__\r
1473         }\r
1474 #endif\r
1475         if(!myackflag)\r
1476                 t0OldService();                 // If we overflow a word, time to call old int handler\r
1477         else\r
1478                 outportb(0x20,0x20);    // Ack the interrupt\r
1479 \r
1480 //00#if 0       // for debugging\r
1481 asm     mov     dx,STATUS_REGISTER_1\r
1482 asm     in      al,dx\r
1483 asm     mov     dx,ATR_INDEX\r
1484 asm     mov     al,ATR_OVERSCAN\r
1485 asm     out     dx,al\r
1486 asm     mov     al,3    // blue\r
1487 asm     out     dx,al\r
1488 asm     mov     al,0x20 // normal\r
1489 asm     out     dx,al\r
1490 //00#endif\r
1491 }\r
1492 \r
1493 ////////////////////////////////////////////////////////////////////////////\r
1494 //\r
1495 //      SDL_ShutDevice() - turns off whatever device was being used for sound fx\r
1496 //\r
1497 ////////////////////////////////////////////////////////////////////////////\r
1498 static void\r
1499 SDL_ShutDevice(void)\r
1500 {\r
1501         switch (SoundMode)\r
1502         {\r
1503         case sdm_PC:\r
1504                 SDL_ShutPC();\r
1505                 break;\r
1506         case sdm_AdLib:\r
1507                 SDL_ShutAL();\r
1508                 break;\r
1509         }\r
1510         SoundMode = sdm_Off;\r
1511 }\r
1512 \r
1513 ///////////////////////////////////////////////////////////////////////////\r
1514 //\r
1515 //      SDL_CleanDevice() - totally shuts down all sound devices\r
1516 //\r
1517 ///////////////////////////////////////////////////////////////////////////\r
1518 static void\r
1519 SDL_CleanDevice(void)\r
1520 {\r
1521         if ((SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib))\r
1522                 SDL_CleanAL();\r
1523 }\r
1524 \r
1525 ///////////////////////////////////////////////////////////////////////////\r
1526 //\r
1527 //      SDL_StartDevice() - turns on whatever device is to be used for sound fx\r
1528 //\r
1529 ///////////////////////////////////////////////////////////////////////////\r
1530 static void\r
1531 SDL_StartDevice(void)\r
1532 {\r
1533         switch (SoundMode)\r
1534         {\r
1535         case sdm_AdLib:\r
1536                 SDL_StartAL();\r
1537                 break;\r
1538         }\r
1539         SoundNumber = SoundPriority = 0;\r
1540 }\r
1541 #if 0\r
1542 static void\r
1543 SDL_SetTimerSpeed(void)\r
1544 {\r
1545         word    rate;\r
1546 \r
1547         if (MusicMode == smm_AdLib)\r
1548                 rate = TickBase * 8;\r
1549         else\r
1550                 rate = TickBase * 2;\r
1551         SDL_SetIntsPerSec(rate);\r
1552 }\r
1553 #endif\r
1554 //      Public routines\r
1555 \r
1556 ///////////////////////////////////////////////////////////////////////////\r
1557 //\r
1558 //      SD_SetSoundMode() - Sets which sound hardware to use for sound effects\r
1559 //\r
1560 ///////////////////////////////////////////////////////////////////////////\r
1561 boolean\r
1562 SD_SetSoundMode(SDMode mode, global_game_variables_t *gvar)\r
1563 {\r
1564         boolean result = false;\r
1565         word    tableoffset;\r
1566 \r
1567         SD_StopSound(gvar);\r
1568 \r
1569 #ifndef _MUSE_\r
1570         if ((mode == sdm_AdLib) && !AdLibPresent)\r
1571                 mode = sdm_PC;\r
1572 \r
1573         switch (mode)\r
1574         {\r
1575         case sdm_Off:\r
1576                 NeedsDigitized = false;\r
1577                 result = true;\r
1578                 break;\r
1579         case sdm_PC:\r
1580                 tableoffset = STARTPCSOUNDS;\r
1581                 NeedsDigitized = false;\r
1582                 result = true;\r
1583                 break;\r
1584         case sdm_AdLib:\r
1585                 if (AdLibPresent)\r
1586                 {\r
1587                         tableoffset = STARTADLIBSOUNDS;\r
1588                         NeedsDigitized = false;\r
1589                         result = true;\r
1590                 }\r
1591                 break;\r
1592         }\r
1593 #else\r
1594         result = true;\r
1595 #endif\r
1596 \r
1597         if (result && (mode != SoundMode))\r
1598         {\r
1599                 SDL_ShutDevice();\r
1600                 SoundMode = mode;\r
1601 #ifndef _MUSE_\r
1602                 SoundTable = (word *)(&gvar->ca.audiosegs[tableoffset]);\r
1603 #endif\r
1604                 SDL_StartDevice();\r
1605         }\r
1606 \r
1607         SDL_SetTimerSpeed();\r
1608 \r
1609         return(result);\r
1610 }\r
1611 \r
1612 ///////////////////////////////////////////////////////////////////////////\r
1613 //\r
1614 //      SD_SetMusicMode() - sets the device to use for background music\r
1615 //\r
1616 ///////////////////////////////////////////////////////////////////////////\r
1617 boolean\r
1618 SD_SetMusicMode(SMMode mode)\r
1619 {\r
1620         boolean result = false;\r
1621 \r
1622         SD_FadeOutMusic();\r
1623         while (SD_MusicPlaying())\r
1624                 ;\r
1625 \r
1626         switch (mode)\r
1627         {\r
1628         case smm_Off:\r
1629                 NeedsMusic = false;\r
1630                 result = true;\r
1631                 break;\r
1632         case smm_AdLib:\r
1633                 if (AdLibPresent)\r
1634                 {\r
1635                         NeedsMusic = true;\r
1636                         result = true;\r
1637                 }\r
1638                 break;\r
1639         }\r
1640 \r
1641         if (result)\r
1642                 MusicMode = mode;\r
1643 \r
1644         SDL_SetTimerSpeed();\r
1645 \r
1646         return(result);\r
1647 }\r
1648 \r
1649 ///////////////////////////////////////////////////////////////////////////\r
1650 //\r
1651 //      SD_Startup() - starts up the Sound Mgr\r
1652 //              Detects all additional sound hardware and installs my ISR\r
1653 //\r
1654 ///////////////////////////////////////////////////////////////////////////\r
1655 void\r
1656 SD_Startup(global_game_variables_t *gvar)\r
1657 {\r
1658         int     i;\r
1659 \r
1660         if (SD_Started)\r
1661                 return;\r
1662 #ifndef SD_USECATA3DSETTIMERSPEED\r
1663 //      SDL_SetDS();\r
1664 #endif\r
1665         ssIsTandy = false;\r
1666 //SS    ssNoCheck = false;\r
1667         alNoCheck = false;\r
1668 //SB    sbNoCheck = false;\r
1669 //SB    sbNoProCheck = false;\r
1670 #ifndef _MUSE_\r
1671         for (i = 1;i < _argc;i++)\r
1672         {\r
1673                 switch (US_CheckParm(_argv[i],ParmStrings))\r
1674                 {\r
1675                 case 0:                                         // No AdLib detection\r
1676                         alNoCheck = true;\r
1677                         break;\r
1678 //SB            case 1:                                         // No SoundBlaster detection\r
1679 //SB                    sbNoCheck = true;\r
1680 //SB                    break;\r
1681 //SB            case 2:                                         // No SoundBlaster Pro detection\r
1682 //SB                    sbNoProCheck = true;\r
1683 //SB                    break;\r
1684 //SS            case 3:\r
1685 //SS                    ssNoCheck = true;               // No Sound Source detection\r
1686 //SS                    break;\r
1687                 case 4:                                         // Tandy Sound Source handling\r
1688                         ssIsTandy = true;\r
1689                         break;\r
1690 //SS            case 5:                                         // Sound Source present at LPT1\r
1691 //SS                    ssPort = 1;\r
1692 //SS                    ssNoCheck = SoundSourcePresent = true;\r
1693 //SS                    break;\r
1694 //SS            case 6:                     // Sound Source present at LPT2\r
1695 //SS                    ssPort = 2;\r
1696 //SS                    ssNoCheck = SoundSourcePresent = true;\r
1697 //SS                    break;\r
1698 //SS            case 7:                     // Sound Source present at LPT3\r
1699 //SS                    ssPort = 3;\r
1700 //SS                    ssNoCheck = SoundSourcePresent = true;\r
1701 //SS                    break;\r
1702                 }\r
1703         }\r
1704 #endif\r
1705 \r
1706         SoundUserHook = 0;\r
1707 \r
1708         t0OldService = getvect(8);      // Get old timer 0 ISR\r
1709 #ifdef SD_USECATA3DSETTIMERSPEED\r
1710         SDL_InitDelay();                        // SDL_InitDelay() uses t0OldService\r
1711 \r
1712         setvect(8,SDL_t0Service);       // Set to my timer 0 ISR\r
1713 #endif\r
1714         LocalTime = TimeCount = alTimeCount = 0;\r
1715 \r
1716         SD_SetSoundMode(sdm_Off, gvar);\r
1717         SD_SetMusicMode(smm_Off);\r
1718 \r
1719 //SS    if (!ssNoCheck)\r
1720 //SS            SoundSourcePresent = SDL_DetectSoundSource();\r
1721 \r
1722         if (!alNoCheck)\r
1723         {\r
1724                 AdLibPresent = SDL_DetectAdLib();\r
1725 //SB            if (AdLibPresent) && !sbNoCheck)\r
1726 //SB            {\r
1727 //SB                    int port = -1;\r
1728 //SB                    char *env = getenv("BLASTER");\r
1729 //SB                    if (env)\r
1730 //SB                    {\r
1731 //SB                            long temp;\r
1732 //SB                            while (*env)\r
1733 //SB                            {\r
1734 //SB                                    while (isspace(*env))\r
1735 //SB                                            env++;\r
1736 //SB\r
1737 //SB                                    switch (toupper(*env))\r
1738 //SB                                    {\r
1739 //SB                                    case 'A':\r
1740 //SB                                            temp = strtol(env + 1,&env,16);\r
1741 //SB                                            if\r
1742 //SB                                            (\r
1743 //SB                                                    (temp >= 0x210)\r
1744 //SB                                            &&      (temp <= 0x260)\r
1745 //SB                                            &&      (!(temp & 0x00f))\r
1746 //SB                                            )\r
1747 //SB                                                    port = (temp - 0x200) >> 4;\r
1748 //SB                                            else\r
1749 //SB                                                    Quit(gvar, "SD_Startup: Unsupported address value in BLASTER");\r
1750 //SB                                            break;\r
1751 //SB                                    case 'I':\r
1752 //SB                                            temp = strtol(env + 1,&env,10);\r
1753 //SB                                            if\r
1754 //SB                                            (\r
1755 //SB                                                    (temp >= 0)\r
1756 //SB                                            &&      (temp <= 10)\r
1757 //SB                                            &&      (sbIntVectors[temp] != -1)\r
1758 //SB                                            )\r
1759 //SB                                            {\r
1760 //SB                                                    sbInterrupt = temp;\r
1761 //SB                                                    sbIntVec = sbIntVectors[sbInterrupt];\r
1762 //SB                                            }\r
1763 //SB                                            else\r
1764 //SB                                                    Quit(gvar, "SD_Startup: Unsupported interrupt value in BLASTER");\r
1765 //SB                                            break;\r
1766 //SB                                    case 'D':\r
1767 //SB                                            temp = strtol(env + 1,&env,10);\r
1768 //SB                                            if ((temp == 0) || (temp == 1) || (temp == 3))\r
1769 //SB                                                    SDL_SBSetDMA(temp);\r
1770 //SB                                            else\r
1771 //SB                                                    Quit(gvar, "SD_Startup: Unsupported DMA value in BLASTER");\r
1772 //SB                                            break;\r
1773 //SB                                    default:\r
1774 //SB                                            while (isspace(*env))\r
1775 //SB                                                    env++;\r
1776 //SB                                            while (*env && !isspace(*env))\r
1777 //SB                                                    env++;\r
1778 //SB                                            break;\r
1779 //SB                                    }\r
1780 //SB                            }\r
1781 //SB                    }\r
1782 //SB                    SoundBlasterPresent = SDL_DetectSoundBlaster(port);\r
1783 //SB            }\r
1784         }\r
1785 \r
1786         for (i = 0;i < 255;i++)\r
1787                 pcSoundLookup[i] = i * 60;\r
1788 \r
1789 //SB    if (SoundBlasterPresent)\r
1790 //SB            SDL_StartSB();\r
1791 \r
1792 //++++  SDL_SetupDigi(gvar);\r
1793 \r
1794         SD_Started = true;\r
1795 }\r
1796 \r
1797 ///////////////////////////////////////////////////////////////////////////\r
1798 //\r
1799 //      SD_Default() - Sets up the default behaviour for the Sound Mgr whether\r
1800 //              the config file was present or not.\r
1801 //\r
1802 ///////////////////////////////////////////////////////////////////////////\r
1803 void\r
1804 SD_Default(boolean gotit,SDMode sd,SMMode sm, global_game_variables_t *gvar)\r
1805 {\r
1806         boolean gotsd,gotsm;\r
1807 \r
1808         gotsd = gotsm = gotit;\r
1809 \r
1810         if (gotsd)      // Make sure requested sound hardware is available\r
1811         {\r
1812                 switch (sd)\r
1813                 {\r
1814                 case sdm_AdLib:\r
1815                         gotsd = AdLibPresent;\r
1816                         break;\r
1817                 }\r
1818         }\r
1819         if (!gotsd)\r
1820         {\r
1821                 if (AdLibPresent)\r
1822                         sd = sdm_AdLib;\r
1823                 else\r
1824                         sd = sdm_PC;\r
1825         }\r
1826         if (sd != SoundMode)\r
1827                 SD_SetSoundMode(sd, gvar);\r
1828 \r
1829 \r
1830         if (gotsm)      // Make sure requested music hardware is available\r
1831         {\r
1832                 switch (sm)\r
1833                 {\r
1834                 case sdm_AdLib:\r
1835                         gotsm = AdLibPresent;\r
1836                         break;\r
1837                 }\r
1838         }\r
1839         if (!gotsm)\r
1840         {\r
1841                 if (AdLibPresent)\r
1842                         sm = smm_AdLib;\r
1843         }\r
1844         if (sm != MusicMode)\r
1845                 SD_SetMusicMode(sm);\r
1846 }\r
1847 \r
1848 ///////////////////////////////////////////////////////////////////////////\r
1849 //\r
1850 //      SD_Shutdown() - shuts down the Sound Mgr\r
1851 //              Removes sound ISR and turns off whatever sound hardware was active\r
1852 //\r
1853 ///////////////////////////////////////////////////////////////////////////\r
1854 void\r
1855 SD_Shutdown(global_game_variables_t *gvar)\r
1856 {\r
1857         if (!SD_Started)\r
1858                 return;\r
1859 \r
1860         SD_MusicOff();\r
1861         SD_StopSound(gvar);\r
1862         SDL_ShutDevice();\r
1863         SDL_CleanDevice();\r
1864 \r
1865 //SB    if (SoundBlasterPresent)\r
1866 //SB            SDL_ShutSB();\r
1867 \r
1868 //SS    if (SoundSourcePresent)\r
1869 //SS            SDL_ShutSS();\r
1870 \r
1871         asm     pushf\r
1872         asm     cli\r
1873 \r
1874         SDL_SetTimer0(0);\r
1875 \r
1876         setvect(8,t0OldService);\r
1877 \r
1878         asm     popf\r
1879 \r
1880         SD_Started = false;\r
1881 }\r
1882 \r
1883 ///////////////////////////////////////////////////////////////////////////\r
1884 //\r
1885 //      SD_SetUserHook() - sets the routine that the Sound Mgr calls every 1/70th\r
1886 //              of a second from its timer 0 ISR\r
1887 //\r
1888 ///////////////////////////////////////////////////////////////////////////\r
1889 void\r
1890 SD_SetUserHook(void (* hook)(void))\r
1891 {\r
1892         SoundUserHook = hook;\r
1893 }\r
1894 \r
1895 ///////////////////////////////////////////////////////////////////////////\r
1896 //\r
1897 //      SD_PositionSound() - Sets up a stereo imaging location for the next\r
1898 //              sound to be played. Each channel ranges from 0 to 15.\r
1899 //\r
1900 ///////////////////////////////////////////////////////////////////////////\r
1901 void\r
1902 SD_PositionSound(int leftvol,int rightvol)\r
1903 {\r
1904         LeftPosition = leftvol;\r
1905         RightPosition = rightvol;\r
1906         nextsoundpos = true;\r
1907 }\r
1908 \r
1909 ///////////////////////////////////////////////////////////////////////////\r
1910 //\r
1911 //      SD_PlaySound() - plays the specified sound on the appropriate hardware\r
1912 //\r
1913 ///////////////////////////////////////////////////////////////////////////\r
1914 boolean\r
1915 SD_PlaySound(soundnames sound, global_game_variables_t *gvar)\r
1916 {\r
1917         boolean         ispos;\r
1918         SoundCommon     far *s;\r
1919         int     lp,rp;\r
1920 \r
1921         lp = LeftPosition;\r
1922         rp = RightPosition;\r
1923         LeftPosition = 0;\r
1924         RightPosition = 0;\r
1925 \r
1926         ispos = nextsoundpos;\r
1927         nextsoundpos = false;\r
1928 \r
1929         if (sound == -1)\r
1930                 return(false);\r
1931 \r
1932         s = MK_FP(SoundTable[sound],0);\r
1933         if ((SoundMode != sdm_Off) && !s)\r
1934                 Quit(gvar, "SD_PlaySound() - Uncached sound");\r
1935 \r
1936         if ((DigiMode != sds_Off) && (DigiMap[sound] != -1))\r
1937         {\r
1938                 if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
1939                 {\r
1940                         if (s->priority < SoundPriority)\r
1941                                 return(false);\r
1942 \r
1943                         SDL_PCStopSound();\r
1944 \r
1945                         SD_PlayDigitized(DigiMap[sound],lp,rp, gvar);\r
1946                         SoundPositioned = ispos;\r
1947                         SoundNumber = sound;\r
1948                         SoundPriority = s->priority;\r
1949                 }\r
1950                 else\r
1951                 {\r
1952                 asm     pushf\r
1953                 asm     cli\r
1954                         if (DigiPriority && !DigiNumber)\r
1955                         {\r
1956                         asm     popf\r
1957                                 Quit(gvar, "SD_PlaySound: Priority without a sound");\r
1958                         }\r
1959                 asm     popf\r
1960 \r
1961                         if (s->priority < DigiPriority)\r
1962                                 return(false);\r
1963 \r
1964                         SD_PlayDigitized(DigiMap[sound],lp,rp, gvar);\r
1965                         SoundPositioned = ispos;\r
1966                         DigiNumber = sound;\r
1967                         DigiPriority = s->priority;\r
1968                 }\r
1969 \r
1970                 return(true);\r
1971         }\r
1972 \r
1973         if (SoundMode == sdm_Off)\r
1974                 return(false);\r
1975         if (!s->length)\r
1976                 Quit(gvar, "SD_PlaySound() - Zero length sound");\r
1977         if (s->priority < SoundPriority)\r
1978                 return(false);\r
1979 \r
1980         switch (SoundMode)\r
1981         {\r
1982         case sdm_PC:\r
1983                 SDL_PCPlaySound((void far *)s);\r
1984                 break;\r
1985         case sdm_AdLib:\r
1986                 SDL_ALPlaySound((void far *)s, gvar);\r
1987                 break;\r
1988         }\r
1989 \r
1990         SoundNumber = sound;\r
1991         SoundPriority = s->priority;\r
1992 \r
1993         return(false);\r
1994 }\r
1995 \r
1996 ///////////////////////////////////////////////////////////////////////////\r
1997 //\r
1998 //      SD_SoundPlaying() - returns the sound number that's playing, or 0 if\r
1999 //              no sound is playing\r
2000 //\r
2001 ///////////////////////////////////////////////////////////////////////////\r
2002 word\r
2003 SD_SoundPlaying(void)\r
2004 {\r
2005         boolean result = false;\r
2006 \r
2007         switch (SoundMode)\r
2008         {\r
2009         case sdm_PC:\r
2010                 result = pcSound? true : false;\r
2011                 break;\r
2012         case sdm_AdLib:\r
2013                 result = alSound? true : false;\r
2014                 break;\r
2015         }\r
2016 \r
2017         if (result)\r
2018                 return(SoundNumber);\r
2019         else\r
2020                 return(false);\r
2021 }\r
2022 \r
2023 ///////////////////////////////////////////////////////////////////////////\r
2024 //\r
2025 //      SD_StopSound() - if a sound is playing, stops it\r
2026 //\r
2027 ///////////////////////////////////////////////////////////////////////////\r
2028 void\r
2029 SD_StopSound(global_game_variables_t *gvar)\r
2030 {\r
2031         if (DigiPlaying)\r
2032                 SD_StopDigitized(gvar);\r
2033 \r
2034         switch (SoundMode)\r
2035         {\r
2036         case sdm_PC:\r
2037                 SDL_PCStopSound();\r
2038                 break;\r
2039         case sdm_AdLib:\r
2040                 SDL_ALStopSound();\r
2041                 break;\r
2042         }\r
2043 \r
2044         SoundPositioned = false;\r
2045 \r
2046         SDL_SoundFinished();\r
2047 }\r
2048 \r
2049 ///////////////////////////////////////////////////////////////////////////\r
2050 //\r
2051 //      SD_WaitSoundDone() - waits until the current sound is done playing\r
2052 //\r
2053 ///////////////////////////////////////////////////////////////////////////\r
2054 void\r
2055 SD_WaitSoundDone(void)\r
2056 {\r
2057         while (SD_SoundPlaying())\r
2058                 ;\r
2059 }\r
2060 \r
2061 ///////////////////////////////////////////////////////////////////////////\r
2062 //\r
2063 //      SD_MusicOn() - turns on the sequencer\r
2064 //\r
2065 ///////////////////////////////////////////////////////////////////////////\r
2066 void\r
2067 SD_MusicOn(void)\r
2068 {\r
2069         sqActive = true;\r
2070 }\r
2071 \r
2072 ///////////////////////////////////////////////////////////////////////////\r
2073 //\r
2074 //      SD_MusicOff() - turns off the sequencer and any playing notes\r
2075 //\r
2076 ///////////////////////////////////////////////////////////////////////////\r
2077 void\r
2078 SD_MusicOff(void)\r
2079 {\r
2080         word    i;\r
2081 \r
2082 \r
2083         switch (MusicMode)\r
2084         {\r
2085         case smm_AdLib:\r
2086                 alFXReg = 0;\r
2087                 alOut(alEffects,0);\r
2088                 for (i = 0;i < sqMaxTracks;i++)\r
2089                         alOut(alFreqH + i + 1,0);\r
2090                 break;\r
2091         }\r
2092         sqActive = false;\r
2093 }\r
2094 \r
2095 ///////////////////////////////////////////////////////////////////////////\r
2096 //\r
2097 //      SD_StartMusic() - starts playing the music pointed to\r
2098 //\r
2099 ///////////////////////////////////////////////////////////////////////////\r
2100 void\r
2101 SD_StartMusic(MusicGroup far *music)\r
2102 {\r
2103         SD_MusicOff();\r
2104 asm     pushf\r
2105 asm     cli\r
2106 \r
2107         if (MusicMode == smm_AdLib)\r
2108         {\r
2109                 sqHackPtr = sqHack = music->values;\r
2110                 sqHackSeqLen = sqHackLen = music->length;\r
2111                 sqHackTime = 0;\r
2112                 alTimeCount = 0;\r
2113                 SD_MusicOn();\r
2114         }\r
2115 \r
2116 asm     popf\r
2117 }\r
2118 \r
2119 ///////////////////////////////////////////////////////////////////////////\r
2120 //\r
2121 //      SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()\r
2122 //              to see if the fadeout is complete\r
2123 //\r
2124 ///////////////////////////////////////////////////////////////////////////\r
2125 void\r
2126 SD_FadeOutMusic(void)\r
2127 {\r
2128         switch (MusicMode)\r
2129         {\r
2130         case smm_AdLib:\r
2131                 // DEBUG - quick hack to turn the music off\r
2132                 SD_MusicOff();\r
2133                 break;\r
2134         }\r
2135 }\r
2136 \r
2137 ///////////////////////////////////////////////////////////////////////////\r
2138 //\r
2139 //      SD_MusicPlaying() - returns true if music is currently playing, false if\r
2140 //              not\r
2141 //\r
2142 ///////////////////////////////////////////////////////////////////////////\r
2143 boolean\r
2144 SD_MusicPlaying(void)\r
2145 {\r
2146         boolean result;\r
2147 \r
2148         switch (MusicMode)\r
2149         {\r
2150         case smm_AdLib:\r
2151                 result = false;\r
2152                 // DEBUG - not written\r
2153                 break;\r
2154         default:\r
2155                 result = false;\r
2156         }\r
2157 \r
2158         return(result);\r
2159 }\r
2160 \r
2161 //#if 0\r
2162 //\r
2163 // SD ASS!\r
2164 //\r
2165 \r
2166 //variables for these assembly functions\r
2167 volatile boolean pcindicate;\r
2168 volatile unsigned/*boolean*/ MyDS;\r
2169 \r
2170 void SDL_SetDS()\r
2171 {\r
2172         __asm {\r
2173                 mov     ax,ds\r
2174                 mov     [cs:MyDS],ds\r
2175                 ret\r
2176         }\r
2177 }\r
2178 \r
2179 //\r
2180 \r
2181 // Timer 0 ISR for 7000Hz interrupts\r
2182 void interrupt SDL_t0ExtremeAsmService(void)\r
2183 {\r
2184         if(pcindicate)\r
2185         {\r
2186                 if(pcSound)\r
2187                 {\r
2188                         SDL_setPCSpeaker(((*pcSound++)&0x80)>>6);\r
2189                         pcLengthLeft--;\r
2190                         if(!pcLengthLeft)\r
2191                         {\r
2192                                 pcSound=0;\r
2193                                 SDL_turnOffPCSpeaker();\r
2194                                 SDL_DigitizedDoneInIRQ();\r
2195                         }\r
2196                 }\r
2197         }\r
2198         extreme++;\r
2199         if(extreme>=10)\r
2200         {\r
2201                 extreme=0;\r
2202                 SDL_DoFast();\r
2203         }\r
2204         else\r
2205                 outp(0x20,0x20);\r
2206 }\r
2207 \r
2208 //\r
2209 \r
2210 void SDL_IndicatePC(boolean ind)\r
2211 {\r
2212         pcindicate=ind;\r
2213 }\r
2214 \r
2215 void\r
2216 SDL_DigitizedDoneInIRQ(void)\r
2217 {\r
2218         if (DigiNextAddr)\r
2219         {\r
2220                 SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen/*,true*/);\r
2221                 DigiNextAddr = nil;\r
2222                 DigiMissed = false;\r
2223         }\r
2224         else\r
2225         {\r
2226                 if (DigiLastSegment)\r
2227                 {\r
2228                         DigiPlaying = false;\r
2229                         DigiLastSegment = false;\r
2230                         if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
2231                         {\r
2232                                 SDL_SoundFinished();\r
2233                         }\r
2234                         else\r
2235                         {\r
2236                                 DigiNumber = (soundnames) 0;\r
2237                                 DigiPriority = 0;\r
2238                         }\r
2239                         SoundPositioned = false;\r
2240                 }\r
2241                 else\r
2242                         DigiMissed = true;\r
2243         }\r
2244 }\r
2245 \r
2246 #if 0\r
2247 // Inside an interrupt handler interrupts should already be disabled\r
2248 // so don't disable them again and cause V86 exceptions which cost\r
2249 // aprox. 300 processor tics!\r
2250 \r
2251 //static\r
2252 void alOutInIRQ(byte n,byte b)\r
2253 {\r
2254         __asm {\r
2255                 mov     dx,0x388\r
2256                 mov     al,[n]\r
2257                 out     dx,al\r
2258                 in      al,dx\r
2259                 in      al,dx\r
2260                 in      al,dx\r
2261                 in      al,dx\r
2262                 in      al,dx\r
2263                 in      al,dx\r
2264                 inc     dx\r
2265                 mov     al,[b]\r
2266                 out     dx,al\r
2267 \r
2268                 dec     dx\r
2269                 in      al,dx\r
2270                 in      al,dx\r
2271                 in      al,dx\r
2272                 in      al,dx\r
2273                 in      al,dx\r
2274                 in      al,dx\r
2275                 in      al,dx\r
2276                 in      al,dx\r
2277                 in      al,dx\r
2278                 in      al,dx\r
2279 \r
2280                 in      al,dx\r
2281                 in      al,dx\r
2282                 in      al,dx\r
2283                 in      al,dx\r
2284                 in      al,dx\r
2285                 in      al,dx\r
2286                 in      al,dx\r
2287                 in      al,dx\r
2288                 in      al,dx\r
2289                 in      al,dx\r
2290 \r
2291                 in      al,dx\r
2292                 in      al,dx\r
2293                 in      al,dx\r
2294                 in      al,dx\r
2295                 in      al,dx\r
2296                 in      al,dx\r
2297                 in      al,dx\r
2298                 in      al,dx\r
2299                 in      al,dx\r
2300                 in      al,dx\r
2301 \r
2302                 in      al,dx\r
2303                 in      al,dx\r
2304                 in      al,dx\r
2305                 in      al,dx\r
2306                 in      al,dx\r
2307         }\r
2308 }\r
2309 #endif\r