home *** CD-ROM | disk | FTP | other *** search
- {****************************************************************************}
- { }
- { MODULE: DevSB }
- { }
- { DESCRIPTION: Device driver for the Sound Blaster sound card and }
- { compatibles, including the Sound Blaster Pro, Sound }
- { Booster, etc... }
- { Uses both: DMA and timer polling. }
- { }
- { AUTHOR: Juan Carlos Arévalo }
- { }
- { MODIFICATIONS: Nobody (yet ;-) }
- { }
- { HISTORY: 18-Oct-1992 Documentation. It doesn't allow the stereo }
- { of the SB Pro yet. }
- { 12-Nov-1992 SB Pro driver included. Speed-ups and fixes. }
- { }
- { (C) 1992 VangeliSTeam }
- {____________________________________________________________________________}
-
- UNIT DevSB;
-
- INTERFACE
-
- CONST
- SBDevID = 'SBlaster-Mono';
- DMASBDevID = 'DMA-SB-Mono';
- DMASBSterDevID = 'DMA-SB-Stereo';
- DMASBMixDevID = 'Mix-DMA-SB-Stereo';
- DMASBMix2DevID = 'Mix2-DMA-SB-Stereo';
-
- CONST
- SbCmdTimeout : WORD = 100; { $10 DSP Command timeout. }
- SbSplTimeout : WORD = 10; { $10 DSP Parameter timeout. }
-
- SbStereoMix : BYTE = 2; { Stereo mixing algorithm. }
-
- SbProMixMasterVol : BYTE = 255; { Master volume of the SB Pro mixer. }
- SbProMixDACVol : BYTE = 255; { DAC volume. }
- SbProMixFMVol : BYTE = 255; { FM music volume. }
- SbProMixFilter : BOOLEAN = FALSE; { TRUE = Activate SB Pro output filter. }
-
-
- PROCEDURE SBInit (Hz: WORD);
- PROCEDURE SBEnd;
-
-
-
-
- IMPLEMENTATION
-
- USES Dos,
- SoundDevices, StrConst,
- Kbd, Debugging, SoundBlaster, Hardware;
-
-
-
-
-
- FUNCTION SBName : TDevName; FAR;
- BEGIN
- SBName := GetString(StrDevSBName);
- END;
-
- FUNCTION DMASBName : TDevName; FAR;
- BEGIN
- DMASBName := GetString(StrDevDMASBName);
- END;
-
- FUNCTION DMASBSterName : TDevName; FAR;
- BEGIN
- DMASBSterName := GetString(StrDevDMASBSterName);
- END;
-
- FUNCTION DMASBMixName : TDevName; FAR;
- BEGIN
- DMASBMixName := GetString(StrDevDMASBMixName);
- END;
-
- FUNCTION DMASBMix2Name : TDevName; FAR;
- BEGIN
- DMASBMix2Name := GetString(StrDevDMASBMix2Name);
- END;
-
-
-
-
- {$L DEVSB}
-
-
-
-
- (******)
-
- PROCEDURE SBInit(Hz: WORD);
- BEGIN
- SbRegInit;
- CalcTimerData(Hz);
- InitTimer;
- END;
-
-
- PROCEDURE SBIntHandler; FAR; EXTERNAL;
-
-
- PROCEDURE SBChgHz(Hz: WORD); FAR;
- BEGIN
- CalcTimerData(Hz);
- InitTimer;
- END;
-
- PROCEDURE DevPoll; FAR;
- BEGIN
- END;
-
-
-
-
- PROCEDURE SBEnd;
- BEGIN
- SbRegDone;
- END;
-
-
- CONST
- SBData : TSoundDevice = (
- DevID : SBDevID;
- DMA : FALSE
- );
-
- (******)
-
-
-
-
- FUNCTION GetDMACount : WORD;
- VAR
- c : BYTE;
- BEGIN
- PORT[$0C] := 0; {clear BYTE POINTER flip-flop TO lower BYTE}
-
- c := PORT[$03];
- GetDMACount := c + 256*WORD(PORT[$03]);
- END;
-
-
-
- CONST
- OldDMAIrq : POINTER = NIL;
-
- DMAPlacedInBuf : WORD = 0;
-
- PROCEDURE DMAIrq; FAR; FORWARD;
- PROCEDURE DoDMA; FORWARD;
-
- {
-
- FUNCTION LimitHz(Hz: WORD; Output: BOOLEAN);
- BEGIN
-
- IF Hz < 4000 THEN Hz := 4000;
- IF (NOT DoHiSpeed) OR (SbStereo AND NOT Sb16Detected) THEN
- IF Hz > 23000 THEN Hz := 23000;
-
- LimitHz := Hz;
- END;
-
-
-
- FUNCTION CalcTimeConst(Hz: WORD) : BYTE;
- VAR
- TimeConst : BYTE;
- BEGIN
- Hz := LimitHz(Hz, TRUE);
-
- IF SbStereo AND NOT Sb16Detected THEN
- BEGIN
- TimeConst := Hi(65536 - 128000000 DIV Hz);
- SoundHz := 500000 DIV (256 - WORD(TimeConst));
- END
- ELSE IF (NOT Sb16Detect) AND (NOT DoHiSpeed) THEN
- BEGIN
- TimeConst := 256 - 1000000 DIV Hz;
- SoundHz := 1000000 DIV (256 - WORD(TimeConst));
- END
- ELSE
- BEGIN
- TimeConst := Hi(65536 - 256000000 DIV Hz);
- SoundHz := 1000000 DIV (256 - WORD(TimeConst));
- END;
-
- CalcTimeConst := TimeConst;
-
- END;
-
-
- FUNCTION CalcHz(tc: BYTE) : WORD;
- VAR
- TimeConst : BYTE;
- BEGIN
-
- IF (NOT Sb16Detect) AND (NOT DoHiSpeed) THEN
- IF SbStereo THEN
- Hz := 500000 DIV (256 - WORD(TimeConst))
- ELSE
- Hz := 1000000 DIV (256 - WORD(TimeConst))
- ELSE
- Hz := 1000000 DIV (256 - WORD(TimeConst));
-
- CalcHz := Hz;
-
- END;
- }
-
-
- FUNCTION DMASBGetRealFreq(Hz: WORD) : WORD; FAR;
- VAR
- i : WORD;
- NHz1 : WORD;
- NHz2 : WORD;
- BEGIN
- IF Hz < 4000 THEN Hz := 4000;
- IF (NOT DoHiSpeed) OR (SbStereo AND NOT Sb16Detected) THEN
- IF Hz > 21800 THEN Hz := 21800;
-
- i := Hi(65536 - (256000000 DIV Hz));
- NHz1 := 1000000 DIV (256 - i);
- NHz2 := 1000000 DIV (256 - i - 1);
-
- IF ABS(INTEGER(NHz1 - Hz)) > ABS(INTEGER(NHz2 - Hz)) THEN NHz1 := NHz2;
-
- DMASBGetRealFreq := NHz1;
- END;
-
-
- FUNCTION DMASBProGetRealFreq(Hz: WORD) : WORD; FAR;
- VAR
- i : WORD;
- NHz1 : WORD;
- NHz2 : WORD;
- BEGIN
- IF Sb16Detected THEN
- BEGIN
- DMASBProGetRealFreq := DMASBGetRealFreq(Hz);
- EXIT;
- END;
-
- IF Hz < 4000 THEN Hz := 4000;
- IF (NOT DoHiSpeed) OR SbStereo THEN
- IF Hz > 21800 THEN Hz := 21800;
-
- i := Hi(65536 - (128000000 DIV Hz));
- NHz1 := 500000 DIV (256 - i);
- NHz2 := 500000 DIV (256 - i - 1);
-
- IF ABS(INTEGER(NHz1 - Hz)) > ABS(INTEGER(NHz2 - Hz)) THEN NHz1 := NHz2;
-
- DMASBProGetRealFreq := NHz1;
- END;
-
-
- PROCEDURE DMASBCalcTimerData(Hz: WORD);
- BEGIN
- CalcTimerData(PeriodicHz);
-
- Hz := ActiveDevice^.GetRealFreqProc(Hz);
-
- IF SbStereo AND NOT Sb16Detected THEN
- BEGIN
- TimeConst := Hi(65536 - 128000000 DIV Hz);
- SoundHz := 500000 DIV (256 - WORD(TimeConst));
- END
- ELSE
- BEGIN
- TimeConst := Hi(65536 - 256000000 DIV Hz);
- SoundHz := 1000000 DIV (256 - WORD(TimeConst));
- END;
- END;
-
-
-
- FUNCTION SbMonoDetect : BOOLEAN; FAR;
- BEGIN
- SbRegInit;
- SbProInit;
- Sb16Init;
- SbMonoDetect := SbRegDetect;
- END;
-
-
- FUNCTION SbStereoDetect : BOOLEAN; FAR;
- BEGIN
- SbRegInit;
- SbProInit;
- Sb16Init;
- SbStereoDetect := SbProDetect OR Sb16Detect;
- END;
-
-
-
- PROCEDURE DMASBInit(Hz: WORD);
- BEGIN
- SbRegInit;
- SbProInit;
- Sb16Init;
-
- IF OldDMAIrq = NIL THEN BEGIN
- OldDMAIrq := SetIRQVector(SbIrq, @DMAIrq);
- EnableIRQ(SbIrq);
- END;
-
- DMASet(SbDMAChan, $58, DMABuffer, DMABufferSize);
-
- SbProSetStereo(SbStereo);
- DMASBCalcTimerData(Hz);
- InitTimer;
-
- SbUpdateTimeConst;
-
- DMAStopped := FALSE;
- DMAStop := FALSE;
- END;
-
-
- PROCEDURE DMASBMonoInit(Hz: WORD); FAR;
- BEGIN
- SbStereo := FALSE;
- Sb16Bit := FALSE;
- DMASbInit(Hz);
- END;
-
-
- PROCEDURE DMASBSterInit(Hz: WORD); FAR;
- BEGIN
- SbStereo := TRUE;
- Sb16Bit := FALSE;
- SbStereoMix := 0;
- DMASbInit(Hz);
- END;
-
-
- PROCEDURE DMASBMixInit(Hz: WORD); FAR;
- BEGIN
- SbStereo := TRUE;
- Sb16Bit := FALSE;
- SbStereoMix := 1;
- DMASbInit(Hz);
- END;
-
-
- PROCEDURE DMASBMix2Init(Hz: WORD); FAR;
- BEGIN
- SbStereo := TRUE;
- Sb16Bit := FALSE;
- SbStereoMix := 2;
- DMASbInit(Hz);
- END;
-
-
- PROCEDURE DMASBChgHz(Hz: WORD); FAR;
- BEGIN
- DMASBCalcTimerData(Hz);
- END;
-
-
- PROCEDURE DMASBEnd; FAR;
- BEGIN
-
- IF OldDMAIrq <> NIL THEN BEGIN
- DMAStopped := FALSE;
- DMAStop := TRUE;
-
- ASM PUSHF; STI END;
-
- WHILE (NOT DMAStopped) AND (NOT DeviceIdling) DO;
-
- ASM POPF END;
-
- SetIRQVector(SbIrq, OldDMAIrq);
- OldDMAIrq := NIL;
- END;
- DisableIRQ(SbIrq);
- END;
-
-
-
-
- (*
- PROCEDURE DMAXchgBuffs; ASSEMBLER;
- ASM
- MOV DX,WORD PTR [DMABuffer1+2]
- MOV SI,WORD PTR [DMABuffer1]
- MOV BX,WORD PTR [DMABuffer1Full]
- LES DI, [DMABuffer2]
- MOV AX,WORD PTR [DMABuffer2Full]
- MOV WORD PTR [DMABuffer1],DI
- MOV WORD PTR [DMABuffer1+2],ES
- MOV WORD PTR [DMABuffer1Full],AX
- MOV WORD PTR [DMABuffer2],SI
- MOV WORD PTR [DMABuffer2+2],DX
- MOV WORD PTR [DMABuffer2Full],BX
- END;
- *)
-
-
- (*
- PROCEDURE AdjustBufferPointers;
- VAR
- o : WORD;
- BEGIN
- o := DMAPlacedInBuf;
- IF SbStereo THEN INC(o, o);
- IF Sb16Bit THEN INC(o, o);
-
- IF DMABuffer1 = DMABuffer THEN
- DMABuffer2 := Ptr(SEG(DMABuffer^),OFS(DMABuffer^) + o)
- ELSE
- DMABuffer1 := Ptr(SEG(DMABuffer^),OFS(DMABuffer^) + o);
- END;
- *)
-
-
- PROCEDURE Dump8Channels; FORWARD;
-
-
- PROCEDURE DMADoGetBuff; ASSEMBLER;
- ASM
- {
- PUSH 0
- PUSH 0
- PUSH $FF
- CALL SetBorder
- }
-
- CALL DoGetBuffer
-
- ADD [DMAPlacedInBuf],AX
-
- {
- PUSH 0
- PUSH $FF
- PUSH 0
- CALL SetBorder
- MOV AX,[DMAPlacedInBuf]
- }
-
- CMP AX,10
- JNC @@nofin
-
- {
- XOR AX,AX
- MOV [DMAPlacedInBuf],AX
- }
- JMP @@Fin1
-
- @@nofin:
-
- MOV BL,[SbStereo]
- AND BL,BL
- JZ @@1
- ADD AX,AX
- @@1:
-
- PUSH AX
- CALL GetDMACount
- MOV BX,DMABufferSize - 1
- SUB BX,AX
- ADD BX,WORD PTR [DMABuffer]
- MOV CX,BX
- SUB BX,WORD PTR [DMABufferPtr]
- JNC @@5
- ADD BX,DMABufferSize
- @@5: POP AX
- PUSH AX
- SUB BX,AX
- JNC @@6
- { INC [PleaseFallBack]}
- ADD AX,BX
- JNZ @@6
-
- { DEC [PleaseFallBack]}
- POP AX
- PUSH AX
- @@6:
- POP BX
- {
- PUSH AX
- MOV BX,WORD PTR [DMABufferPtr]
- SUB BX,CX
- JNC @@7
- ADD BX,DMABufferSize
- @@7: POP AX
- SUB BX,AX
- JNC @@8
- ADD AX,BX
- @@8:
- }
- MOV BL,[SbStereo]
- AND BL,BL
- JZ @@2
- SHR AX,1
- @@2:
- JMP Dump8Channels
- @@Fin1:
- END;
-
-
-
- PROCEDURE Dump8Channels; ASSEMBLER;
- CONST
- First : BOOLEAN = TRUE;
- ASM
- MOV DL,[First]
- AND DL,DL
- JZ @@nofirst
-
- MOV WORD PTR [CS:@@Data11-2],0
- MOV WORD PTR [CS:@@Data12-2],0
- MOV WORD PTR [CS:@@Data21-2],0
- MOV WORD PTR [CS:@@Data22-2],0
- MOV [First],0
-
- @@nofirst:
- MOV DL,[DoEqualice]
- MOV BYTE PTR [CS:@@Equalice],DL
-
- MOV BL,[SbStereo]
- MOV BH,[SbStereoMix]
- LES DI,[DMABufferPtr]
- MOV CX,[DMABufferEnd]
- MOV WORD PTR [CS:@@moData1-2],CX
- MOV WORD PTR [CS:@@stData1-2],CX
- MOV WORD PTR [CS:@@m1Data1-2],CX
- MOV WORD PTR [CS:@@m2Data1-2],CX
- LDS SI,[Sounding]
- CLD
- MOV CX,AX
- AND BL,BL
- JNZ @@stereo
- @@lpfillmono:
- MOV AX,[DS:SI]
- ADD AX,[DS:SI+6]
- ADD AX,[DS:SI+8]
- ADD AX,[DS:SI+14]
- ADD AX,[DS:SI+16]
- ADD AX,[DS:SI+22]
- ADD AX,[DS:SI+24]
- ADD AX,[DS:SI+30]
-
- MOV BX,[DS:SI+2]
- ADD BX,[DS:SI+4]
- ADD BX,[DS:SI+10]
- ADD BX,[DS:SI+12]
- ADD BX,[DS:SI+18]
- ADD BX,[DS:SI+20]
- ADD BX,[DS:SI+26]
- ADD BX,[DS:SI+28]
-
- ADD AX,BX
- JNO @@nooverf
- JS @@posit
- MOV AX,-32768
- JMP @@nooverf
- @@posit: MOV AX,32767
- @@nooverf:
-
-
-
-
- MOV DL,BYTE PTR [CS:@@Equalice]
- AND DL,DL
- JZ @@noequal
-
- PUSH CX
-
- PUSH AX
-
- CWD
-
- MOV BX,1234
- @@Data11:
- MOV CX,1234
- @@Data12:
-
- SAR CX,1
- RCR BX,1
- SAR CX,1
- RCR BX,1
- SUB AX,BX
- SBB DX,CX
-
- SAR CX,1
- RCR BX,1
- SUB AX,BX
- SBB DX,CX
-
- MOV WORD PTR [CS:@@Data11-2],AX
- MOV WORD PTR [CS:@@Data12-2],DX
-
- MOV BX,AX
- MOV CX,DX
-
- POP AX
-
- PUSH BX
- PUSH CX
-
- CWD
-
- MOV BX,1234
- @@Data21:
- MOV CX,1234
- @@Data22:
-
- SAR CX,1
- RCR BX,1
- ADD AX,BX
- ADC DX,CX
-
- SAR CX,1
- RCR BX,1
- ADD AX,BX
- ADC DX,CX
-
- SAR CX,1
- RCR BX,1
- SAR CX,1
- RCR BX,1
- ADD AX,BX
- ADC DX,CX
-
- MOV WORD PTR [CS:@@Data21-2],AX
- MOV WORD PTR [CS:@@Data22-2],DX
-
- POP CX
- POP BX
-
- SUB AX,BX
- SBB DX,CX
- SUB AX,BX
- SBB DX,CX
-
- SAR DX,1
- RCR AX,1
-
- CMP DX,0
- JG @@up
- JNE @@neg
- CMP AX,32768
- JC @@nada
- @@up: MOV AX,32767
- JMP @@nada
- @@neg: CMP DX,-1
- JNZ @@dw
- CMP AX,32768
- JNC @@nada
- @@dw: MOV AX,-32768
- @@nada:
-
- POP CX
-
- @@noequal:
-
-
-
-
-
- (*
-
- MOV DX,AX
- MOV BX,1234
- NEG BX
- @@Data1:
- ADD AX,BX
- JNO @@1nooverf
- JS @@1posit
- MOV AX,-32767
- JMP @@1nooverf
- @@1posit: MOV AX,32767
- @@1nooverf:
- { MOV WORD PTR [CS:@@Data1-2],AX}
- XCHG AX,DX
-
- MOV BX,1234
- @@Data2:
- ADD AX,BX
- JNO @@2nooverf
- JS @@2posit
- MOV AX,-32767
- JMP @@2nooverf
- @@2posit: MOV AX,32767
- @@2nooverf:
- { MOV WORD PTR [CS:@@Data2-2],AX}
-
- SUB AX,DX
- JNO @@3nooverf
- JS @@3posit
- MOV AX,-32767
- JMP @@3nooverf
- @@3posit: MOV AX,32767
- @@3nooverf:
-
- NEG DX
- ADD AX,DX
- JNO @@4nooverf
- JS @@4posit
- MOV AX,-32767
- JMP @@4nooverf
- @@4posit: MOV AX,32767
- @@4nooverf:
- ADD AX,DX
- JNO @@5nooverf
- JS @@5posit
- MOV AX,-32767
- JMP @@5nooverf
- @@5posit: MOV AX,32767
- @@5nooverf:
-
- *)
-
-
-
-
-
-
-
- XOR AH,80h
- MOV AL,AH
- STOSB
- CMP DI,$1234
- @@moData1:
- JB @@monocont
- SUB DI,DMABufferSize
- @@monocont: ADD SI,MaxChannels*2
- DEC CX
- JNZ @@lpfillmono
- { LOOP @@lpfillmono}
- JMP @@Fin
-
-
-
- @@Equalice: DB 0
-
-
-
-
-
-
- @@stereo: AND BH,BH
- JNZ @@domix
- @@lpfillster:
- MOV AX,[DS:SI]
- ADD AX,[DS:SI+6]
- ADD AX,[DS:SI+8]
- ADD AX,[DS:SI+14]
- ADD AX,[DS:SI+16]
- ADD AX,[DS:SI+22]
- ADD AX,[DS:SI+24]
- ADD AX,[DS:SI+30]
-
- MOV BX,[DS:SI+2]
- ADD BX,[DS:SI+4]
- ADD BX,[DS:SI+10]
- ADD BX,[DS:SI+12]
- ADD BX,[DS:SI+18]
- ADD BX,[DS:SI+20]
- ADD BX,[DS:SI+26]
- ADD BX,[DS:SI+28]
-
- ADD BX,BX
- JNO @@stnooverf1
- JS @@stposit1
- MOV BX,-32768
- JMP @@stnooverf1
- @@stposit1: MOV BX,32767
- @@stnooverf1:
- ADD AX,AX
- JNO @@stnooverf2
- JS @@stposit2
- MOV AX,-32768
- JMP @@stnooverf2
- @@stposit2: MOV AX,32767
- @@stnooverf2:
- MOV AL,BH
- XOR AX,8080h
- STOSW
- CMP DI,$1234
- @@stData1:
- JB @@stercont
- SUB DI,DMABufferSize
- @@stercont: ADD SI,MaxChannels*2
- LOOP @@lpfillster
- JMP @@Fin
-
- @@domix: DEC BH
- JNZ @@domix2
- @@lpfillmix1:
- MOV AX,[DS:SI]
- ADD AX,[DS:SI+6]
- ADD AX,[DS:SI+8]
- ADD AX,[DS:SI+14]
- ADD AX,[DS:SI+16]
- ADD AX,[DS:SI+22]
- ADD AX,[DS:SI+24]
- ADD AX,[DS:SI+30]
-
- MOV BX,[DS:SI+2]
- ADD BX,[DS:SI+4]
- ADD BX,[DS:SI+10]
- ADD BX,[DS:SI+12]
- ADD BX,[DS:SI+18]
- ADD BX,[DS:SI+20]
- ADD BX,[DS:SI+26]
- ADD BX,[DS:SI+28]
-
- MOV DX,AX
- ADD AX,BX
- JNO @@m1nooverf0
- RCR AX,1
- JMP @@m1ovc0
- @@m1nooverf0: SAR AX,1
- @@m1ovc0:
- ADD BX,AX
- JNO @@m1nooverf1
- JS @@m1posit1
- MOV BX,-32768
- JMP @@m1nooverf1
- @@m1posit1: MOV BX,32767
- @@m1nooverf1:
- ADD AX,DX
- JNO @@m1nooverf2
- JS @@m1posit2
- MOV AX,-32768
- JMP @@m1nooverf2
- @@m1posit2: MOV AX,32767
- @@m1nooverf2:
- MOV AL,BH
- XOR AX,8080h
- STOSW
- CMP DI,$1234
- @@m1Data1:
- JB @@mix1cont
- SUB DI,DMABufferSize
- @@mix1cont: ADD SI,MaxChannels*2
- LOOP @@lpfillmix1
- JMP @@Fin
-
-
-
- @@domix2:
- @@lpfillmix2:
- MOV AX,[DS:SI]
- ADD AX,[DS:SI+6]
- ADD AX,[DS:SI+8]
- ADD AX,[DS:SI+14]
- ADD AX,[DS:SI+16]
- ADD AX,[DS:SI+22]
- ADD AX,[DS:SI+24]
- ADD AX,[DS:SI+30]
-
- MOV BX,[DS:SI+2]
- ADD BX,[DS:SI+4]
- ADD BX,[DS:SI+10]
- ADD BX,[DS:SI+12]
- ADD BX,[DS:SI+18]
- ADD BX,[DS:SI+20]
- ADD BX,[DS:SI+26]
- ADD BX,[DS:SI+28]
-
-
- SAR BX,1
- SAR AX,1
- MOV DX,AX
- ADD AX,BX
-
- MOV [WORD PTR CS:@@datastm2-2],AX
- SAR AX,1
- ADD AX,1234
- @@datastm2:
- JNO @@m2nooverf1
- JS @@m2posit1
- MOV AX,-32768
- JMP @@m2nooverf1
- @@m2posit1: MOV AX,32767
- @@m2nooverf1:
- ADD DX,AX
- JNO @@m2nooverf2
- JS @@m2posit2
- MOV DX,-32768
- JMP @@m2nooverf2
- @@m2posit2: MOV DX,32767
- @@m2nooverf2:
- ADD AX,BX
- JNO @@m2nooverf3
- JS @@m2posit3
- MOV AX,-32768
- JMP @@m2nooverf3
- @@m2posit3: MOV AX,32767
- @@m2nooverf3:
- MOV AL,DH
- XOR AX,8080h
- STOSW
- CMP DI,$1234
- @@m2Data1:
- JB @@mix2cont
- SUB DI,DMABufferSize
- @@mix2cont: ADD SI,MaxChannels*2
- LOOP @@lpfillmix2
-
- @@Fin: MOV AX,SEG(@Data)
- MOV DS,AX
- MOV WORD PTR [DMABufferPtr],DI
-
- {
- PUSH 0
- PUSH 0
- PUSH 0
- CALL SetBorder
- }
- END;
-
-
-
-
- PROCEDURE DoDMA; ASSEMBLER;
- CONST
- OLDDMABP : WORD = 0;
- OLDDMACT : WORD = 0;
- ASM
- CLI
-
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH DI
- PUSH SI
- PUSH ES
- {
- CALL GetDMACount
- INC AX
- MOV BX,[OLDDMACT]
- MOV [OLDDMACT],AX
- SUB BX,AX
- JNC @@8
- ADD BX,DMABufferSize
- @@8:
- PUSH 0
- PUSH BX
- PUSH $70
- CALL WriteNum
-
- MOV BX,WORD PTR [DMABufferPtr]
- MOV AX,[OLDDMABP]
- MOV [OLDDMABP],BX
- SUB BX,AX
- JNC @@9
- ADD BX,DMABufferSize
- @@9:
- PUSH 20
- PUSH BX
- PUSH $70
- CALL WriteNum
- }
-
- PUSHA
- PUSH 'l'
- PUSH $02
- CALL WriteChar
- POPA
-
- MOV AX,[DMAPlacedInBuf]
- AND AX,AX
- JNZ @@haybuf
-
- INC [PleaseFallBack]
-
- PUSHA
- PUSH 'd'
- PUSH $70
- CALL WriteChar
- POPA
-
- CALL DMADoGetBuff
-
- CALL DMADoGetBuff
-
- MOV AX,[DMAPlacedInBuf]
- AND AX,AX
- JNZ @@haybuf
- INC AH
- MOV [DeviceIdling],AH
- JMP @@Fin
-
- @@haybuf: XOR BH,BH
- MOV [DeviceIdling],BH
-
- CALL SbUpdateTimeConst
-
- MOV CX,[DMAPlacedInBuf]
- PUSH CX
- PUSH 1
- CALL SbPlaySample
-
- XOR AX,AX
- MOV [DMAPlacedInBuf],AX
-
- @@7:
- CALL DMADoGetBuff
- CALL DMADoGetBuff
-
- @@Fin: POP ES
- POP SI
- POP DI
- POP DX
- POP CX
- POP BX
- END;
-
-
-
-
- PROCEDURE DMATim; FAR; ASSEMBLER;
- ASM
- CLI
-
- PUSH AX
- PUSH DS
- PUSH ES
-
- MOV AX,SEG(@Data)
- MOV DS,AX
-
- PUSHA
- PUSH 't'
- PUSH $20
- CALL WriteChar
- POPA
-
- MOV AL,[DMAIrqWatch]
- CMP AL,20
- JNC @@dowatch
-
- MOV AL,[DeviceIdling]
- AND AL,AL
- JZ @@notneeded
-
- PUSHA
- CALL InitTimer
- POPA
-
- JMP @@noack
- @@dowatch:
- PUSH DX
- MOV DX,[DSP8AckPort]
- IN AL,DX
- MOV DX,[DSPLifePort]
- IN AL,DX
- POP DX
-
- @@noack: MOV AL,[DMAStop]
- AND AL,AL
- JZ @@notstop
-
- MOV [DMAStopped],AL
- MOV [DeviceIdling],AL
- JMP @@notneeded
-
- @@notstop: XOR AL,AL
- MOV [DeviceIdling],AL
-
- CALL DoDMA
-
- XOR AL,AL
- MOV [DMAIrqWatch],AL
-
- @@notneeded: MOV AL,[DMAIrqWatch]
- CMP AL,100
- JNC @@noinc
-
- INC [DMAIrqWatch]
-
- @@noinc: MOV AX,[SystemClockIncr]
- ADD [SystemClockCount],AX
- JNC @@nosys
-
- PUSHF
- CALL CSOldInt8
- JMP @@sisys
-
- @@nosys: MOV AL,20h
- OUT 20h,AL
-
- @@sisys: STI
-
- MOV AL,[DMAStop]
- AND AL,AL
- JZ @@notstop2
-
- MOV [DMAStopped],AL
- MOV [DeviceIdling],AL
- JMP @@donothing
-
- @@notstop2: PUSHA
- CALL PeriodicProc
- MOV AX,[DMAPlacedInBuf]
- AND AX,AX
- JNZ @@nogetbuff
-
- CLI
- CALL DMADoGetBuff
- STI
-
- @@nogetbuff:
- POPA
-
- @@donothing:
- POP ES
- POP DS
- POP AX
- IRET
- END;
-
- PROCEDURE DMAIrq; ASSEMBLER;
- CONST
- Old83 : BYTE = 0;
- ASM
- CLI
-
- PUSH DX
- PUSH AX
- PUSH DS
- PUSH ES
-
- MOV AX,SEG(@Data)
- MOV DS,AX
- {
- MOV DX,[MixAddrPort]
- MOV AL,$83
- OUT DX,AL
- INC DL
- IN AL,DX
- MOV [Old83],AL
- DEC DL
-
- MOV AL,$83
- OUT DX,AL
- INC DL
- XOR AL,AL
- OUT DX,AL
- }
- MOV DX,[DSP8AckPort]
- IN AL,DX
-
- MOV DX,[DSPLifePort]
- IN AL,DX
-
-
- PUSHA
- PUSH 'i'
- PUSH $07
- CALL WriteChar
- POPA
-
- XOR AL,AL
- MOV [DMAIrqWatch],AL
-
- MOV AL,[DMAStop]
- AND AL,AL
- JZ @@nostop
-
- MOV [DMAStopped],AL
- MOV [DeviceIdling],AL
- JMP @@Fin
- @@nostop:
- CALL DoDMA
- @@Fin:
- {
- PUSHA
- PUSH 100
- PUSH $DA
- CALL SbWriteByte
- POPA
-
- PUSHA
- PUSH 100
- PUSH $45
- CALL SbWriteByte
- POPA
- }
- {
- MOV DX,[MixAddrPort]
- MOV AL,$83
- OUT DX,AL
- INC DL
- MOV AL,[Old83]
- OUT DX,AL
- }
- MOV AX,[SbIrq]
- CMP AL,10
- JNZ @@not10
-
- MOV AL,$20
- OUT $A0,AL
-
- @@not10: MOV AL,$20
- OUT $20,AL
-
- POP ES
- POP DS
- POP AX
- POP DX
- IRET
- END;
-
-
- CONST
- DMASBData : TSoundDevice = (
- DevID : DMASBDevID;
- DMA : TRUE
- );
-
-
- CONST
- DMASBSterData : TSoundDevice = (
- DevID : DMASBSterDevID;
- DMA : TRUE
- );
-
-
- CONST
- DMASBMixData : TSoundDevice = (
- DevID : DMASBMixDevID;
- DMA : TRUE
- );
-
-
- CONST
- DMASBMix2Data : TSoundDevice = (
- DevID : DMASBMix2DevID;
- DMA : TRUE
- );
-
-
-
-
- (******)
-
- BEGIN
-
- WITH SBData DO BEGIN
- Name := SBName;
- AutoDetect := SbRegDetect;
- InitRut := SBInit;
- ChgHzProc := SBChgHz;
- GetRealFreqProc := GetRealFreq;
- TimerHandler := SBIntHandler;
- PollRut := DevPoll;
- EndRut := SBEnd;
- END;
-
- WITH DMASBData DO BEGIN
- Name := DMASBName;
- AutoDetect := SbMonoDetect;
- InitRut := DMASBMonoInit;
- ChgHzProc := DMASBChgHz;
- GetRealFreqProc := DMASBGetRealFreq;
- TimerHandler := DMATim;
- PollRut := DevPoll;
- EndRut := DMASBEnd;
- END;
-
- WITH DMASBSterData DO BEGIN
- Name := DMASBSterName;
- AutoDetect := SbStereoDetect;
- InitRut := DMASBSterInit;
- ChgHzProc := DMASBChgHz;
- GetRealFreqProc := DMASBProGetRealFreq;
- TimerHandler := DMATim;
- PollRut := DevPoll;
- EndRut := DMASBEnd;
- END;
-
- WITH DMASBMixData DO BEGIN
- Name := DMASBMixName;
- AutoDetect := SbStereoDetect;
- InitRut := DMASBMixInit;
- ChgHzProc := DMASBChgHz;
- GetRealFreqProc := DMASBProGetRealFreq;
- TimerHandler := DMATim;
- PollRut := DevPoll;
- EndRut := DMASBEnd;
- END;
-
- WITH DMASBMix2Data DO BEGIN
- Name := DMASBMix2Name;
- AutoDetect := SbStereoDetect;
- InitRut := DMASBMix2Init;
- ChgHzProc := DMASBChgHz;
- GetRealFreqProc := DMASBProGetRealFreq;
- TimerHandler := DMATim;
- PollRut := DevPoll;
- EndRut := DMASBEnd;
- END;
-
- InitDevice(@DMASBMix2Data);
- InitDevice(@DMASBMixData);
- InitDevice(@DMASBSterData);
- InitDevice(@DMASBData);
- InitDevice(@SBData);
-
- END.
-