.386P Segment DriverHeader PARA Public 'Code' Use16 Assume CS:Driver, DS:Nothing ;***** Driver Header ******* include drhead.inc EndS Segment Driver PARA Public 'Code' Use16 Assume CS:Driver, DS:Nothing ORG 0 StartDriver: include vtable.inc ;******** Required ProcedureTable ************* include reqproc.inc ;********************************** STEREOENABLED EQU 1 DMABUFFERLENGTH EQU 8192 MIXRESOLUTION EQU 32 ; 32 bit mixing for the PAS16 MIXTABLESIZE EQU 2*256*65 TIMERCONST EQU 11932 Debug1 DB 0 Debug2 DW 0 PAS16Msg DB "Pro Audio 16 Spectrum found", 13 DB "Port ", 0FDh, "Xh, IRQ ", 0FDh, "D, DMA ", 0FDh, "D", 0 PAS16NoMemoryMsg DB "Pro Audio 16 Spectrum found", 13 DB "Error: Insufficient memory", 0 ReinitMsg DB "Pro Audio 16 Spectrum reinitialised", 0 ConfigErrorMsg DB "Error saving configuration to ITPAS16.DRV", 0 ConfigOKMsg DB "Configuration saved to ITPAS16.DRV", 0 DriverName DB "ITPAS16.DRV", 0 Forced DB 0 Stereo DB 0 MixVolume DW 0 BytesToMix DW 1000 MixSpeed DW 44100 PASMixConst DW 0 MixSegment DW 0 DMASegment DW 0 MixTransferOffset DW 0 MixTransferRemaining DW 0 CONFIGURATIONOFFSET EQU $+128 CONFIGSIZE EQU 6 MixMode DW 0 MixModeOffset DW 0 Filter DW 0 IMR DW 0 OldIRQHandler DD 0 FilterValue DD 0 FilterValue2 DD 0 TimerAccumulator DW 0 DMALengthTable Label Byte DB 1, 3, 5, 7, 0C2h, 0C6h, 0CAh, 0CEh ;********************************** PAS16ScreenList Label DW 6 DW Near Ptr IdleFunctionList DW Near Ptr GlobalKeyLink DW Near Ptr FullScreenBox ; 0 DW Near Ptr ScreenHeader DW Near Ptr FillHeader DW Near Ptr PAS16HeaderLine DW Near Ptr DriverText DW Near Ptr MixModeText DW Near Ptr MixModeButton1 ; 6 DW Near Ptr MixModeButton2 ; DW Near Ptr MixModeButton3 ; 8 DW Near Ptr MixModeButton4 ; 9 DW Near Ptr FilterText DW Near Ptr FilterButton1 ; 11 DW Near Ptr FilterButton2 DW Near Ptr FilterButton3 DW 0 PAS16HeaderLine DW 10 DB "Pro Audio Spectrum 16 Driver", 0 EmptyObject DW 1 DB 0, 0 DB 0 DB 0 DriverText DW 1 DB 26, 48 DB 21h DB "Pro Audio Spectrum 16 Driver 1.0 for Impulse Tracker", 0 GlobalKeyLink DB 7 GlobalKeyLink2 DD 0 IdleFunctionList DD 0 DD 0 FillHeader DW 8 FillHeader2 DD 0 FullScreenBox DW 0 DB 0, 0, 79, 49 DB 4 ScreenHeader DW 8 ScreenHeader2 DD 0 MixModeText DW 1 DB 2, 13 DB 20h DB "Mixing Mode", 0 MixModeButton1 DW 2 DW 0FFFFh, 7, 0FFFFh, 0FFFFh DW 0 DW 0, 0 DW 6 DW Offset GetMixMode DriverSegment1 DW 0 DW 0 DW Offset SetMixMode DriverSegment2 DW 0 DB 3, 15, 32, 17, 8 DB 0 DB " 16 Bit, Non-Interpolated", 0 MixModeButton2 DW 2 DW 6, 8, 0FFFFh, 0FFFFh DW 0 DW 0, 0 DW 6 DW Offset GetMixMode DriverSegment3 DW 0 DW 2 DW Offset SetMixMode DriverSegment4 DW 0 DB 3, 18, 32, 20, 8 DB 0 DB " 16 Bit, Interpolated", 0 MixModeButton3 DW 2 DW 7, 9, 0FFFFh, 0FFFFh DW 0 DW 0, 0 DW 6 DW Offset GetMixMode DriverSegment5 DW 0 DW 4 DW Offset SetMixMode DriverSegment6 DW 0 DB 3, 21, 32, 23, 8 DB 0 DB " 32 Bit, Non-Interpolated", 0 MixModeButton4 DW 2 DW 8, 11, 0FFFFh, 0FFFFh DW 0 DW 0, 0 DW 6 DW Offset GetMixMode DriverSegment7 DW 0 DW 6 DW Offset SetMixMode DriverSegment8 DW 0 DB 3, 24, 32, 26, 8 DB 0 DB " 32 Bit, Interpolated", 0 FilterText DW 1 DB 2, 28 DB 20h DB "Filter mode", 0 FilterButton1 DW 2 DW 9, 12, 0FFFFh, 0FFFFh DW 0 DW 0, 0 DW 6 DW Offset GetFilter DriverSegment9 DW 0 DW 0 DW Offset SetFilter DriverSegment10 DW 0 DB 3, 30, 29, 32, 8 DB 0 DB " No Filter", 0 FilterButton2 DW 2 DW 11, 13, 0FFFFh, 0FFFFh DW 0 DW 0, 0 DW 6 DW Offset GetFilter DriverSegment11 DW 0 DW 1 DW Offset SetFilter DriverSegment12 DW 0 DB 3, 33, 29, 35, 8 DB 0 DB " 50% Filter", 0 FilterButton3 DW 2 DW 12, 0FFFFh, 0FFFFh, 0FFFFh DW 0 DW 0, 0 DW 6 DW Offset GetFilter DriverSegment13 DW 0 DW 2 DW Offset SetFilter DriverSegment14 DW 0 DB 3, 36, 29, 38, 8 DB 0 DB " 75% Filter", 0 VolumeTable DB 6 Dup (0) ; ÄÄ MixingRoutines ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MixBufferPos DW 0 include dma.inc include mix.inc include m12bit.mix include m12biti.mix include m32bit.mix include m32biti.mix MixFunctionTables Label include m12bit.inc ; contains the tables include m12biti.inc include m32bit.inc include m32biti.inc ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RelocationTable Label Word DW Offset DriverSegment1, Offset DriverSegment2 DW Offset DriverSegment3, Offset DriverSegment4 DW Offset DriverSegment5, Offset DriverSegment6 DW Offset DriverSegment7, Offset DriverSegment8 DW Offset DriverSegment9, Offset DriverSegment10 DW Offset DriverSegment11, Offset DriverSegment12 DW Offset DriverSegment13, Offset DriverSegment14 DW 0 ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc GetMixMode Far Push CS Pop ES Mov DI, Offset MixMode Ret EndP GetMixMode ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc GetFilter Far Push CS Pop ES Mov DI, Offset Filter Ret EndP GetFilter ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc SetFilter Far Mov AX, [SI+22] Mov CS:FilterValue, 0 Mov CS:Filter, AX ClI Jmp SetMixModeChain EndP SetFilter ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc SetMixMode Far Mov AX, [SI+22] ClI Mov CS:MixMode, AX Mov BX, 180 Mul BX Mov CS:MixModeOffset, AX Mov DS, Word Ptr [CS:RecalculateAllVolumes+2] Call CS:RecalculateAllVolumes StI SetMixModeChain: Call GotoHomeDirectory ; Now to save config into driver file. Push CS Pop DS Assume DS:Driver Mov AX, 3D02h ; Read write access Mov DX, Offset DriverName Mov SI, Offset ConfigErrorMsg Int 21h JC SetMixMode1 Mov BX, AX Mov AX, 4200h Xor CX, CX Mov DX, Offset CONFIGURATIONOFFSET Int 21h JC SetMixMode2 Mov AH, 40h Mov CX, CONFIGSIZE Mov DX, Offset MixMode Int 21h SetMixMode2: PushF Mov AH, 3Eh Int 21h PopF JC SetMixMode1 Mov SI, Offset ConfigOKMsg SetMixMode1: Mov BX, 40 Call SetInfoLine Mov AX, 1 Ret EndP SetMixMode Assume DS:Nothing ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc GetMixSpeed Assume DS:Driver Push AX Push CX Push DX Mov DX, 12h Mov AX, 34DCh Mov CX, PASMixConst Cmp CS:Stereo, 0 JE GetMixSpeed1 And CX, Not 1 GetMixSpeed1: Div CX GetMixSpeed2: Mov MixSpeed, AX Pop DX Pop CX Pop AX Ret EndP GetMixSpeed Assume DS:Nothing ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc GetPASMixConst ; Work out value.. and nearest ; mixspeed value. PushA Push DS Push CS Pop DS Assume DS:Driver Mov AX, CmdLineMixSpeed Mov CX, MixSpeed Test AX, AX JZ GetPASMixConst1 Mov CX, 44100 Cmp AX, CX JA GetPASMixConst1 Mov CX, 12000 Cmp AX, CX JB GetPASMixConst1 Mov CX, AX GetPASMixConst1: Mov MixSpeed, CX Mov DX, 012h Mov AX, 34DCh Div CX Mov PASMixConst, AX Mov BX, AX Pop DS PopA Ret EndP GetPASMixConst Assume DS:Nothing ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc TestPAS ; AX = port Push AX Mov DX, 803h ; Default is 0B8Bh Xor DX, AX ; DX = Interrupt Control port In AL, DX Cmp AL, 0FFh JE TestPAS1 Mov AH, AL Xor AL, 11100000b Out DX, AL Jmp $+2 Jmp $+2 In AL, DX Cmp AL, AH XChg AH, AL Out DX, AL JNE TestPAS1 Pop AX Push AX Mov DX, AX ; PAS 16? Xor DX, 0EF8Bh xor 388h In AL, DX Test AL, 8 JZ TestPAS1 Pop AX ClC Ret TestPAS1: Pop AX StC Ret EndP TestPAS ; ÄÄ DetectCard ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Returns carry set if error, else carry clear. Has to setup internal vars ; (eg. appropriate IRQ/DMA whatever). ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc DetectCard Far Push CS Pop DS Assume DS:Driver Mov AX, 0BC00h Mov BX, '??' Xor CX, CX Xor DX, DX Int 2Fh Xor BX, CX Xor BX, DX Cmp BX, 'M'*256+'V' JE DetectPAS4 ; MVSound.Sys installed! DetectPAS7: StC Ret DetectPAS4: Mov AX, BasePort Cmp AX, 0FFFFh JE DetectPAS1 Cmp AX, 388h JE DetectPAS6 Cmp AX, 384h JE DetectPAS6 Cmp AX, 38Ch JE DetectPAS6 Cmp AX, 288h JNE DetectPAS7 DetectPAS6: Call TestPAS JNC DetectPAS2 Ret DetectPAS1: Mov AX, 388h Call TestPAS JNC DetectPAS2 Mov AX, 384h Call TestPAS JNC DetectPAS2 Mov AX, 38Ch Call TestPAS JNC DetectPAS2 Mov AX, 288h Call TestPAS JNC DetectPAS2 Ret ; No card! DetectPAS2: Push AX Mov AX, 0BC04h Int 2Fh Cmp AX, 'M'*256+'V' JNE DetectPAS3 Pop AX Mov BasePort, AX Mov DMA, BX Mov IRQ, CX Mov AL, [DMALengthTable+BX] Mov Byte Ptr [DMAPort1], AL Mov Byte Ptr [DMAPort2], AL Mov AX, DMABUFFERLENGTH/2 Cmp BX, 4 JB DetectPAS5 ShR AX, 1 DetectPAS5: Mov Word Ptr [DMABufferLength1], AX Mov Word Ptr [DMABufferLength2], AX Mov EAX, 'Jeff' ClC Ret DetectPAS3: Pop AX StC Ret EndP DetectCard Assume DS:Nothing ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MixModeTable Label Word DW Offset Mix0ModeMono, Mix0ModeStereo DW Offset Mix0ModeMono, Mix0ModeStereo DW Offset Mix6ModeMono, Mix6ModeStereo DW Offset Mix6ModeMono, Mix6ModeStereo Proc MixSamples ; Given DS:SI = info tables, CX = numchannels ; 1. Clean buffer ; + update variables ; 2. Update parameters ; 3. Mix func ; 4. Return Push CX Mov CX, BytesToMix Mov ES, MixSegment Mov DI, MIXTABLESIZE Xor EAX, EAX Mov DX, CX Add CX, CX Mov MixTransferOffset, DI ; } Memory write Cmp Stereo, 0 JE MixSamples1 Mov DX, CX MixSamples1: Rep StosD ; } Memory write Mov MixTransferRemaining, DX ; } Pop CX MixSamples2: Test Byte Ptr [SI], 1 JZ MixSamplesEnd2 Cmp Byte Ptr [SI+36h], 100 JE MixSamplesEnd2 Push CX Mov CX, [SI] Test CH, 2 JZ MixSamples3 And Byte Ptr [SI], Not 1 Jmp MixSamplesEnd ; Cmp MixMode, 8 ; Is it volume ramping? ; JB MixSamplesEnd MixSamples3: Test CL, 20h ; New freq? JZ MixSamples5 Mov AX, [SI+10h] Mov DX, [SI+12h] Mov BX, MixSpeed Cmp DX, BX JAE MixSamplesHandleError Div BX ShL EAX, 16 Xor AX, AX Div BX Mov STEPVALUE, EAX MixSamples4: Test CH, 1 JZ MixSamples5 Mov DWord Ptr [SI+1Ch], 0 ; Current Volume = 0 ; for volume sliding. MixSamples5: Test CX, 8440h ; New volume or panning? JZ MixSamplesMix Xor AX, AX Test CH, 8 ; Muted? JNZ MixModeCommon Mov BX, MixMode Add BL, Stereo Add BX, BX Jmp [CS:MixModeTable+BX] Mix0Mode: ; 16-bit mixing, no interpolation Mix0ModeMono: ; and 16-bit mixing, interpolation Mov AL, [SI+20h] ShR AL, 1 Mov [SI+0Ch], AX Mov [SI+0Eh], AX Mov AX, 0 JZ MixModeCommon Mov AL, 30 ; Use left only-mixing for mono Jmp MixModeCommon Mix0ModeStereo: Mov AL, [SI+37h] ; Final pan Cmp AL, 100 JE Mix0ModeSurround Mul Byte Ptr [SI+20h] ; Final volume Add AX, 64 ShR AX, 7 Mov [SI+0Ch], AX ; Store into right volume Mov AL, 64 Sub AL, [SI+37h] Mul Byte Ptr [SI+20h] Add AX, 64 ShR AX, 7 Mov [SI+0Eh], AX ; Left volume Mov CH, AL ; CH = left volume Mov CL, [SI+0Ch] ; CL = right volume Mov AX, 0 Test CX, CX JZ MixModeCommon Mov AL, 30 ; Left only... Test CL, CL JZ MixModeCommon Mov AL, 60 Test CH, CH JZ MixModeCommon Mov AL, 90 Cmp CL, CH JZ MixModeCommon Mov AL, 120 Jmp MixModeCommon Mix0ModeSurround: Mov AL, [SI+20h] ShR AL, 2 Mov [SI+0Ch], AX Mov [SI+0Eh], AX Mov AX, 0 JZ MixModeCommon Mov AL, 150 ; Surround Jmp MixModeCommon Mix6ModeMono: Mov AX, [SI+4Ah] Mul MixVolume ShRD AX, DX, 8 Mov [SI+0Ch], AX Mov [SI+0Eh], AX Test AX, AX JZ MixModeCommon Mov AX, 30 Jmp MixModeCommon Mix6ModeStereo: Mov AL, [SI+37h] ; Final pan Cmp AL, 100 JE Mix6ModeSurround Mul Byte Ptr MixVolume Mul Word Ptr [SI+4Ah] ShRD AX, DX, 14 Mov [SI+0Ch], AX ; Store into right volume Mov BX, AX ShL EAX, 16 Mov AL, 64 ; Do left volume Sub AL, [SI+37h] ; AL = 64-FinalPan Mul Byte Ptr MixVolume Mul Word Ptr [SI+4Ah] ShRD AX, DX, 14 Mov [SI+0Eh], AX Mov ECX, EAX ; BX = right volume ; CX = Left volume Mov AX, 0 Test ECX, ECX JZ MixModeCommon Mov AL, 30 Test BX, BX JZ MixModeCommon Mov AL, 60 Test CX, CX JZ MixModeCommon Mov AL, 90 Cmp CX, BX JE MixModeCommon Mov AL, 120 Jmp MixModeCommon Mix6ModeSurround: Mov AX, [SI+4Ah] Mul MixVolume ShRD AX, DX, 9 Mov [SI+0Ch], AX Mov [SI+0Eh], AX JZ MixModeCommon Mov AX, 150 Jmp MixModeCommon MixModeCommon: ; Requires AX = 30/60/90 etc. depending ; On mixing mode type. ; This will add 180 for 16-bit, ; And sort out loop types. Mov BL, [SI+0Ah] Test Byte Ptr [SI+18h], 2 ; 16 bit? JZ MixModeCommon1 Add AX, 180 MixModeCommon1: Cmp BL, 8 JB MixModeCommon3 ; No loop JE MixModeCommon2 ; Forwards loop Add AX, 10 MixModeCommon2: Add AX, 10 MixModeCommon3: Add AX, Offset MixFunctionTables Add AX, MixModeOffset Mov [SI+8], AX ; Offset... MixSamplesMix: Mov BX, [SI+8] ; BX = offset into Mov EAX, [CS:BX+2] Mov DWord Ptr PreMixFunction, EAX Mov EAX, [CS:BX+6] Mov DWord Ptr MixFunctionSeparateBackwards, EAX Mov AX, BytesToMix Mov MixBlockSize, AX Mov MixBufferOffset, MIXTABLESIZE Mov EAX, CURRENTPOSITION Mov OLDPOSITION, EAX Call Word Ptr [CS:BX] And Word Ptr [SI], 0111100010001101b Jmp MixSamplesEnd MixSamplesHandleError: Mov Word Ptr [SI], 200h Test Byte Ptr [SI+3Ah], 80h JNZ MixSamplesEnd Mov BX, [SI+38h] And Byte Ptr [BX], Not 4 ; Turn off channel MixSamplesEnd: Pop CX MixSamplesEnd2: Add SI, 128 Dec CX JNZ MixSamples2 Ret EndP MixSamples ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc PAS16IRQHandler Push AX Push BX Push DS Push CS Pop DS Assume DS:Driver Add TimerAccumulator, TIMERCONST JC PAS16IRQHandler11 Mov AL, 20h Out 20h, AL Jmp PAS16IRQHandler12 PAS16IRQHandler11: PushF Call [OldIRQHandler] PAS16IRQHandler12: DMAPort1 EQU $+1 In AL, 1 Mov AH, AL DMAPort2 EQU $+1 In AL, 1 XChg AL, AH Mov Debug2, AX Cmp MixBufferPos, 0 JE PAS16IRQHandler13 Xor BX, BX DMABufferLength1 EQU $+1 Cmp AX, 1234h JB PAS16IRQHandler1 Pop DS Pop BX Pop AX IRet PAS16IRQHandler13: Mov BX, DMABUFFERLENGTH/2 DMABufferLength2 EQU $+1 Cmp AX, 1234h JAE PAS16IRQHandler1 Pop DS Pop BX Pop AX IRet PAS16IRQHandler1: Xor MixBufferPos, 1 PushAD Push ES CLD ; OK... time to get next block ; Check whether stereo thing is on.. ; LES DI, [ActualDMAPtr] Add DI, BX Mov BX, DMABUFFERLENGTH/4 ; BX = samples required Mov BP, 8 ; Skip for mono Mov CL, 14 ; Shift for mono Cmp Stereo, 0 JE PAS16IRQHandlerMono Mov BP, 4 ; Stereo skip value. Dec CL PAS16IRQHandlerMono: Call SaveEMSPageFrame Cmp MixTransferRemaining, 0 JNE PAS16IRQHandler4 Assume DS:Nothing PAS16IRQHandler3: Push BX Push CX Push BP Push ES Push DI Call Update Call MixSamples Pop DI Pop ES Pop BP Pop CX Pop BX PAS16IRQHandler4: Mov DS, MixSegment Mov SI, MixTransferOffset Mov DX, BX ; DX = samples to transfer Cmp DX, MixTransferRemaining JBE PAS16IRQHandler5 Mov DX, MixTransferRemaining PAS16IRQHandler5: Push DX Cmp CS:Filter, 1 JB PAS16IRQHandler6 JE PAS16IRQHFilter Cmp CS:Stereo, 0 JE PAS16IRQ3QFilterMono PAS16IRQ3QFilterStereo: Push BX Mov EBX, FilterValue Mov EBP, FilterValue2 ShR DX, 1 PAS16IRQ3QFilterStereo1: Mov EAX, EBX Mov ECX, EBP Add EAX, [SI] Add ECX, [SI+4] SAR EAX, 1 SAR ECX, 1 Add EBX, EAX Add EBP, ECX SAR EBX, 1 SAR EBP, 1 Mov EAX, EBX SAR EAX, 13 Cmp EAX, -8000h JL PAS163QFilterStereoClip1 Cmp EAX, 7FFFh JG PAS163QFilterStereoClip2 PAS16IRQ3QFilterStereo2: StosW Mov EAX, EBP SAR EAX, 13 Cmp EAX, -8000h JL PAS163QFilterStereoClip3 Cmp EAX, 7FFFh JG PAS163QFilterStereoClip4 PAS16IRQ3QFilterStereo3: StosW Add SI, 8 Dec DX JNZ PAS16IRQ3QFilterStereo1 Mov FilterValue, EBX Mov FilterValue2, EBP Pop BX Jmp PAS16MixTransferEnd PAS16IRQ3QFilterMono: Push BX Mov EBX, FilterValue PAS16IRQ3QFilterMono1: Mov EAX, EBX Add EAX, [SI] SAR EAX, 1 Add EBX, EAX SAR EBX, 1 Mov EAX, EBX SAR EAX, 14 Cmp EAX, -8000h JL PAS163QFilterMonoClip1 Cmp EAX, 7FFFh JG PAS163QFilterMonoClip2 PAS16IRQ3QFilterMono2: StosW Add SI, 8 Dec DX JNZ PAS16IRQ3QFilterMono1 Mov FilterValue, EBX Pop BX Jmp PAS16MixTransferEnd PAS16IRQHFilter: Cmp CS:Stereo, 0 JE PAS16IRQHFilterMono PAS16IRQHFilterStereo: Push BX Mov EBX, FilterValue Mov EBP, FilterValue2 ShR DX, 1 PAS16IRQHFilterStereo1: Add EBX, [SI] Add EBP, [SI+4] SAR EBX, 1 SAR EBP, 1 Mov EAX, EBX SAR EAX, 13 Cmp EAX, -8000h JL PAS16HFilterStereoClip1 Cmp EAX, 7FFFh JG PAS16HFilterStereoClip2 PAS16IRQHFilterStereo2: StosW Mov EAX, EBP SAR EAX, 13 Cmp EAX, -8000h JL PAS16HFilterStereoClip3 Cmp EAX, 7FFFh JG PAS16HFilterStereoClip4 PAS16IRQHFilterStereo3: StosW Add SI, 8 Dec DX JNZ PAS16IRQHFilterStereo1 Mov FilterValue, EBX Mov FilterValue2, EBP Pop BX Jmp PAS16MixTransferEnd PAS16IRQHFilterMono: Push BX Mov EBX, FilterValue PAS16IRQHFilterMono1: Add EBX, [SI] SAR EBX, 1 Mov EAX, EBX SAR EAX, 14 Cmp EAX, -8000h JL PAS16HFilterMonoClip1 Cmp EAX, 7FFFh JG PAS16HFilterMonoClip2 PAS16IRQHFilterMono2: StosW Add SI, 8 Dec DX JNZ PAS16IRQHFilterMono1 Mov FilterValue, EBX Pop BX Jmp PAS16MixTransferEnd PAS16IRQHandler6: Mov EAX, [SI] SAR EAX, CL Cmp EAX, -8000h JL PAS16IRQHandlerClip1 Cmp EAX, 7FFFh JG PAS16IRQHandlerClip2 PAS16IRQHandler7: StosW ; } Memory write Add SI, BP Dec DX JNZ PAS16IRQHandler6 PAS16MixTransferEnd: Pop DX Sub MixTransferRemaining, DX ; } Memory write Sub BX, DX JNZ PAS16IRQHandler3 Mov MixTransferOffset, SI ; } Memory write Call RestoreEMSPageFrame Pop ES PopAD Pop DS Pop BX Pop AX IRet PAS16IRQHandlerClip1: Mov AX, 8000h Jmp PAS16IRQHandler7 PAS16IRQHandlerClip2: Mov AX, 7FFFh Jmp PAS16IRQHandler7 PAS16HFilterMonoClip1: Mov AX, 8000h Jmp PAS16IRQHFilterMono2 PAS16HFilterMonoClip2: Mov AX, 7FFFh Jmp PAS16IRQHFilterMono2 PAS16HFilterStereoClip1: Mov AX, 8000h Jmp PAS16IRQHFilterStereo2 PAS16HFilterStereoClip2: Mov AX, 7FFFh Jmp PAS16IRQHFilterStereo2 PAS16HFilterStereoClip3: Mov AX, 8000h Jmp PAS16IRQHFilterStereo3 PAS16HFilterStereoClip4: Mov AX, 7FFFh Jmp PAS16IRQHFilterStereo3 PAS163QFilterMonoClip1: Mov AX, 8000h Jmp PAS16IRQ3QFilterMono2 PAS163QFilterMonoClip2: Mov AX, 7FFFh Jmp PAS16IRQ3QFilterMono2 PAS163QFilterStereoClip1: Mov AX, 8000h Jmp PAS16IRQ3QFilterStereo2 PAS163QFilterStereoClip2: Mov AX, 7FFFh Jmp PAS16IRQ3QFilterStereo2 PAS163QFilterStereoClip3: Mov AX, 8000h Jmp PAS16IRQ3QFilterStereo3 PAS163QFilterStereoClip4: Mov AX, 7FFFh Jmp PAS16IRQ3QFilterStereo3 EndP PAS16IRQHandler Assume DS:Nothing ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc SetIRQ Push EAX Push ES Xor AX, AX Mov ES, AX Mov AL, 34h ; Program IRQ 0. LSB&MSB, Rate gen Out 43h, AL ; bump the interrupt to be called ; 100 times a second. Mov AX, TIMERCONST Out 40h, AL Mov AL, AH Out 40h, AL Mov AX, CS ShL EAX, 16 Mov AX, Offset PAS16IRQHandler ClI XChg [ES:20h], EAX ; Hook to timer interrupt Mov CS:OldIRQHandler, EAX StI Pop ES Pop EAX Ret EndP SetIRQ Assume DS:Nothing ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc ResetIRQ Push EAX Push ES Xor AX, AX Mov ES, AX Mov AL, 34h ; Program IRQ 0. LSB&MSB, Rate gen Out 43h, AL Xor AL, AL Out 40h, AL ; Interrupt called at normal 18.2 times Out 40h, AL Mov EAX, CS:OldIRQHandler Mov [ES:20h], EAX Pop ES Pop EAX Ret EndP ResetIRQ Assume DS:Nothing ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc StopPAS16 Mov DX, BasePort Xor AL, AL Xor DX, 0B89h xor 388h ; Interrupt Status register Out DX, AL Mov DX, BasePort ; Audio filter control Mov AL, 1 Xor DX, 0B8Ah xor 388h ; Disable buffer counter Out DX, AL ; and PAS 16 output Mov DX, BasePort Xor DX, 8389h xor 388h ; SysConfig2 In AL, DX ; Get SysConfig2 And AL, Not 4 ; Reset 8 bits Out DX, AL Mov DX, BasePort Mov AL, 19h ; Mono, L2L, R2R Xor DX, 0F8Ah xor 388h ; Cross channel register Out DX, AL Ret EndP StopPAS16 ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc StartPAS16 ; PushA Push ES Push DS Push CS Pop DS Assume DS:Driver ; Setup DMA Mov BX, DMASegment Xor AX, AX Mov DX, DMA Mov DI, DMABUFFERLENGTH Call SetDMA LES DI, ActualDMAPtr Xor AX, AX Mov CX, DMABUFFERLENGTH/2 Rep StosW Mov MixBufferPos, 0 Mov MixTransferRemaining, 0 Mov DX, BasePort Xor AL, AL Xor DX, 0B89h xor 388h ; Interrupt Status register Out DX, AL Mov DX, BasePort ; Audio filter control Mov AL, 1 Xor DX, 0B8Ah xor 388h ; Disable buffer counter Out DX, AL ; and PAS 16 output Mov DX, BasePort Mov AL, 19h Xor DX, 0F8Ah xor 388h ; Cross channel register Out DX, AL Mov DX, BasePort Xor DX, 138Bh xor 388h ; Timer control, Mov AL, 00110110b ; 36h - set frequency Out DX, AL Mov DX, BasePort Xor DX, 1388h xor 388h Mov AX, PASMixConst Cmp Stereo, 0 JE StartPAS16_2 ShR AX, 1 StartPAS16_2: Out DX, AL Mov AL, AH Out DX, AL Call GetMixSpeed Call GetTempo Call SetTempo Mov DX, BasePort Xor DX, 138Bh xor 388h ; Timer control Mov AL, 01110100b ; 74h - set buffer count Out DX, AL Mov DX, BasePort ; Sample count Mov AX, DMABUFFERLENGTH Xor DX, 1389h xor 388h Cmp DMA, 4 JB StartPAS16_1 ShR AX, 1 StartPAS16_1: Out DX, AL Mov AL, AH Out DX, AL Mov DX, BasePort Xor DX, 8389h xor 388h ; SysConfig2 In AL, DX ; Get SysConfig2 Or AL, 4 ; Set 16 bits Out DX, AL Mov AL, Stereo Xor AL, 1 ; 0 if stereo, 1 if mono. ShL AL, 5 Mov DX, BasePort Or AL, 099h ; Enable DRQ, DAC output Xor DX, 0F8Ah xor 388h Out DX, AL Jmp $+2 Jmp $+2 Or AL, 40h ; Enable PCM Out DX, AL Mov DX, BasePort Xor DX, 0B8Bh xor 388h In AL, DX Or AL, 8 ; Enable sample buffer intr Out DX, AL Mov DX, BasePort ; Disable output&timers Mov AL, 0E1h ; disable mute, enable sample rate ; timer and sample buffer counter. Xor DX, 0B8Ah xor 388h Out DX, AL Pop DS Pop ES PopA Ret Assume DS:Nothing EndP StartPAS16 ;ÄÄ InitSound ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Sets up any memory required for output ; Initiates output ; ; Parameters: AX = Number of Channels ; ; If sucessful, returns: ; Carry flag clear ; DS:SI = pointer to text to display ; AX = parameter 1 in text ; BX = parameter 2 in text ; CX = parameter 3 in text ; DX = parameter 4 in text ; DI = parameter 5 in text ; ; If unsucessful, returns: ; Carry flag set ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc InitSound Far Push CS Pop DS Assume DS:Driver Mov SI, Offset RelocationTable RelocationFix: LodsW Test AX, AX JZ RelocationEnd Mov BX, AX Mov [BX], DS Jmp RelocationFix RelocationEnd: Call GetEMSPageFrame Mov EMSPageFrame, AX In AL, 0A1h Mov AH, AL In AL, 21h Mov IMR, AX Mov ECX, IdleUpdateInfoLine Mov EDX, GlobalKeyList Mov IdleFunctionList, ECX Mov GlobalKeyLink2, EDX Mov ECX, FillHeaderFunction Mov EDX, DrawHeaderFunction Mov FillHeader2, ECX Mov ScreenHeader2, EDX Call GetPASMixConst Mov AX, 2643 Mul MixSpeed Add AX, 0FFFFh AdC DX, 2080 Mov BX, (DMABUFFERLENGTH*2)/16 Add BX, DX ; Allocate MixSegment first Mov AH, 48h Int 21h JNC InitSound1 InitSoundNoMemory: Mov SI, Offset PAS16NoMemoryMsg Ret InitSound1: Mov MixSegment, AX Add AX, DX Mov DMASegment, AX Call SetIRQ Call GetTempo Call SetTempo Mov SI, Offset PAS16Msg Mov AX, BasePort Mov BX, IRQ Mov CX, DMA Ret EndP InitSound Assume DS:Nothing ;ÄÄ ReInitSound ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Reinitialises sound output ; Initiates sound output ; ; Parameters: AX = number of channels. ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc ReInitSound Far PushA Push DS Push ES Push CS Pop DS Assume DS:Driver Call ResetIRQ Call SetIRQ Mov SI, Offset ReInitMsg Mov BX, 40 Call SetInfoLine Mov AL, Stereo Call SetStereo Pop ES Pop DS PopA Ret EndP ReInitSound Assume DS:Nothing ;ÄÄ UnInitSound ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Stops sound output, releases any memory used by driver ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc UnInitSound Far Push CS Pop DS Assume DS:Driver Mov AX, IMR Out 21h, AL Mov AL, AH Out 0A1h, AL Mov AX, MixSegment Test AX, AX JZ UnInitSound1 Mov ES, AX Mov AH, 49h ; Release MixSegment Int 21h Call StopPAS16 Call ResetIRQ UnInitSound1: Ret EndP UnInitSound Assume DS:Nothing ;ÄÄ Poll ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; This procedure is called as often as possible by IT.EXE ; AX = Playmode (0 for nothing in particular, 1 = pattern, 2 = song) ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc Poll Far ; In AL, 1 ; Mov AH, AL ; In AL, 1 ; Mov CS:Debug2, AX Ret EndP Poll ;ÄÄ SetTempo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Parameters: BX = tempo ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc SetTempo Far Push AX Push BX Push DX Push BX Mov AX, MixSpeed Mov BX, AX Xor DX, DX ShL AX, 1 RCL DX, 1 ; DX:AX = Mixspeed*2 ShR BX, 1 ; BX = Mixspeed/2 Add AX, BX AdC DX, 0 ; DX:AX = Mixspeed*2.5 Pop BX ; BX = tempo Div BX Mov BytesToMix, AX Pop DX Pop BX Pop AX Ret EndP SetTempo ;ÄÄ SetMixVolume ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Parameters: AX = MixVolume ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc SetMixVolume Far PushA Push DS Mov BX, AX ; BX = MixVolume Mov CS:MixVolume, BX Mov AX, CS:MixSegment Test AX, AX JZ SetMixVolume2 Mov DS, AX Mov CX, MIXTABLESIZE/2 Mov SI, MIXTABLESIZE-2; Starting point - working backwards SetMixVolume1: Mov AX, CX Dec AX ; AH = volume, AL = wave value. Xor DX, DX XChg AH, DL ; DL = Volume, AX = wave value CBW IMul DX ; DX:AX = Volume * Wave Value ; Ranges -8192->8128 IMul BX ; DX:AX = Volume * Wave Value * Mixing Volume ; Ranges -1048576->1040384 Add AX, 64 AdC DX, 0 ShRD AX, DX, 7 Mov [SI], AX Sub SI, 2 Loop SetMixVolume1 SetMixVolume2: Call RecalculateAllVolumes Pop DS PopA Ret EndP SetMixVolume ;ÄÄ SetStereo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Parameters: AL = Stereo on/off, 0 = off. ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc RecalculateAllFrequencies Call GetChannelTables RecalculateAllFrequencies1: Or Byte Ptr [SI], 32 Add SI, 128 Dec CX JNZ RecalculateAllFrequencies1 Ret EndP RecalculateAllFrequencies Proc SetStereo Far Mov CS:Stereo, AL Cmp CS:MixSegment, 0 JE SetStereo1 Call StopPAS16 Call StartPAS16 Call RecalculateAllFrequencies SetStereo1: Ret EndP SetStereo ;ÄÄ LoadSample ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Parameters: AX = sample to load ; DS:SI points to sample header ; ES:0 points to first sample ; ; Returns: **Carry set if NO error** ; **Carry clear if error** ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ include loadsam.inc ;ÄÄ ReleaseSample ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Parameters: AX = sample to release ; DS:SI points to sample header ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc ReleaseSample Far Ret EndP ReleaseSample ;ÄÄ ResetMemory ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Frees all on-board memory ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc ResetMemory Far Ret EndP ResetMemory ;ÄÄ GetStatus ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Frees all on-board memory ; ; Returns text to show on status line, AX = display parameter ; Carry set if not to show anything. ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc GetStatus Far StC Ret EndP GetStatus ;ÄÄ SoundCardScreen ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ; Function to have driver interactive part of program ; ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc SoundCardScreen Far Mov AX, 5 Mov SI, 1 Mov CX, CS Mov DX, Offset PAS16ScreenList ClC Ret EndP SoundCardScreen ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc GetVariable Far ; Returns AX, given DI Xor AH, AH Mov AL, [CS:VolumeTable+DI] Ret EndP GetVariable ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Proc SetVariable Far ; Given AX, DI Push DS Push DX Push CS Pop DS Assume DS:Driver Mov [VolumeTable+DI], AL Comment ~ Mov DX, BasePort Add DL, 4 Mov AL, 30h Mov AH, [VolumeTable] ShL AH, 3 Out DX, AX Mov AL, 31h Mov AH, [VolumeTable+1] ShL AH, 3 Out DX, AX Mov AL, 44h Mov AH, [VolumeTable+2] ShL AH, 4 Out DX, AX Mov AL, 45h Mov AH, [VolumeTable+3] ShL AH, 4 Out DX, AX Mov AL, 46h Mov AH, [VolumeTable+4] ShL AH, 4 Out DX, AX Mov AL, 47h Mov AH, [VolumeTable+5] ShL AH, 4 Out DX, AX ~ Pop DX Pop DS Ret EndP SetVariable Assume DS:Nothing ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ EndDriver: ;******** Provided Variable Table ************* MaxNumberOfChannels DW 0FFFFh ; Maximum number of channels the ; driver can handle. StopAfterPlay DW 0 DefaultChannels DW 64 DW 5 Dup (0) ;******** Provided Procedure Table ************* ProvidedTableStart: DW Offset DetectCard DW Offset InitSound ; Playing related DW Offset ReinitSound DW Offset UninitSound DW Offset Poll DW Offset SetTempo ; Sound variable related DW Offset SetMixVolume DW Offset SetStereo DW Offset LoadSample ; Sample related DW Offset ReleaseSample DW Offset ResetMemory DW Offset GetStatus ; Returns string to show on status line DW Offset SoundCardScreen ; Sound card 'screen' DW Offset GetVariable ; For interface DW Offset SetVariable ProvidedTableEnd: DW 32-(ProvidedTableEnd-ProvidedTableStart)/2 Dup (0) EndS End