home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 26
/
CD_ASCQ_26_1295.iso
/
voxrom
/
textes
/
repwin08
/
annexes
/
triax
/
sb.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-10-01
|
8KB
|
290 lines
{▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}
{ SB - Unité gestion SB }
{▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}
Unit SB;
INTERFACE {--Globals--------------------------------------------------------}
Var
SBPort : word; {Port de base SB}
SBIrq : byte; {Numéro d'irq SB}
SBDma : byte; {Canal dma SB}
SBDmaDone : boolean; {Transfert dma terminé oui/non}
Procedure SBInit; {Installe handler d'irq}
Procedure SBDone; {UnInstalle handler}
Function SBReset:BOOLEAN; {Reset SB}
Function SBDetect:BOOLEAN; {Detect SB}
Function SBVersion:WORD; {Lit version DSP}
Procedure SBHpOn; {Allume HP}
Procedure SBHpOff; {Eteint HP}
Function SBDirectIn:BYTE; {Direct sample input}
Procedure SBDirectOut(Sample:BYTE); {Direct sample output}
Procedure SBSetFreq(Freq:WORD); {Règle fréquence sampling}
Procedure SBDmaIn(Count:WORD;Address:POINTER); {Lit sample via DMA}
Procedure SBDmaOut(Count:WORD;Address:POINTER); {Sort sample via DMA}
Procedure SBStopDma; {Stop transfert DMA}
Procedure SBContinueDma; {Continue transfert DMA}
IMPLEMENTATION {--Locals----------------------------------------------------}
Uses DOS,DMA;
Const
DSPReset = $06; {Port de reset}
DSPRead = $0a; {Port de lecture}
DSPWrite = $0c; {Port d'écriture}
DSPDataState = $0e; {Port d'état des données}
Var
OldHandlerAddr : pointer; {Ancien handler d'irq}
{▓▓▓▓▓ Low level routines - Lecture/Ecriture/Reset SB ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}
{░░░ SBREAD: Lit un octet sur la SB ░░░}
Function SBRead:BYTE; assembler;
Asm
mov dx,[SBPort]
or dl,DSPDataState
@SBRead_Wait:
in al,dx
or al,al
jns @SBRead_Wait
and dl,0f0h
or dl,DSPRead
in al,dx
End;
{░░░ SBWRITE: Ecrit un octet sur la SB ░░░}
Procedure SBWrite(Data:BYTE); assembler;
Asm
mov dx,[SBPort]
or dl,DSPWrite
@SBWrite_Wait:
in al,dx
or al,al
js @SBWrite_Wait
mov al,[Data]
out dx,al
End;
{▒▒▒ SBRESET: Balance un reset au DSP ▒▒▒}
Function SBReset:BOOLEAN; assembler;
Asm
{░░ Envoie le reset ░░}
mov dx,[SBPort]
or dl,DSPReset
mov al,1
out dx,al
in al,dx
in al,dx
in al,dx
in al,dx
xor al,al
out dx,al
{░░ Attend une réponse de la SB ░░}
and dl,0f0h
or dl,DSPDataState
mov cx,256
@SBReset_Wait:
in al,dx
or al,al
js @SBReset_Test
loop @SBReset_Wait
@SBReset_Failed:
mov al,FALSE
ret
{░░ Teste si on a bien affaire à un DSP ░░}
@SBReset_Test:
and dl,0f0h
or dl,DSPRead
in al,dx
cmp al,0aah
jne @SBReset_Failed
mov al,TRUE
End;
{▓▓▓▓▓ Autodétection de la SB ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}
{░░░ SBDetectPORT: Détecte le port de base SB ░░░}
Function SBDetectPort:BOOLEAN;
Begin
SBDetectPort:=FALSE;
SBPort:=$210;
Repeat
If SBReset then
Begin
SBDetectPort:=TRUE;
Exit;
End;
Inc(SBPort,$10);
Until SBPort>$280;
End;
{░░░ SBDetectIRQ: Détecte l'irq SB ░░░}
Function SBDetectIrq:BOOLEAN;
Const Irqs : array[0..4] of byte = (2,3,5,7,10);
Var
IrqIndex : byte;
IrqDelay : word;
Begin
SBDetectIrq:=FALSE;
SBHpOff;
{░░ Parcourt toutes les irqs possibles à travers IrqIndex ░░}
IrqIndex:=0;
Repeat
SBIrq:=Irqs[IrqIndex];
SBInit; {Installe handler}
SBDmaOut($0002,NIL); {Envoie un chti bloc}
{░░ Attend pour voir si la SB répond ░░}
For IrqDelay:=0 to $ffff do
If SBDmaDone then
Begin
SBDetectIrq:=TRUE; {░ Oui-> cool on a trouvé! ░}
Exit;
End;
{░ Non-> alors irq suivante ░}
SBDone; {Uninstall handler}
Inc(IrqIndex);
Until IrqIndex > 4;
End;
{▒▒▒ SBDetect: Auto-détecte les port,irq,dma SB ▒▒▒}
Function SBDetect:BOOLEAN;
Begin
SBDetect:=FALSE;
SBDma:=1; {Disons que ouais... (en général c'est ça..)}
If not SBDetectPort then exit;
If not SBDetectIrq then exit;
SBDetect:=TRUE;
End;
{▒▒▒ SBVersion: Lit le numéro de version du DSP ▒▒▒}
Function SBVersion:WORD;
Begin
SBWrite($E1);
SBVersion:=SBRead+SBRead shl 8;
End;
{▓▓▓▓▓ Gestion du Haut-Parleur ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}
{▒▒▒ SBHpON: Allume le Haut-Parleur ▒▒▒}
Procedure SBHpOn;
Begin
SBWrite($D1);
End;
{▒▒▒ SBHpOFF: Eteint le Haut-Parleur ▒▒▒}
Procedure SBHpOff;
Begin
SBWrite($D3);
End;
{▓▓▓▓▓ Entrée/Sortie directe de samples ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}
{▒▒▒ SBDirectIN: Lit un sample direct from SB ▒▒▒}
Function SBDirectIn:BYTE;
Begin
SBWrite($20);
SBDirectIn:=SBRead;
End;
{▒▒▒ SBDirectOut: Sort un sample direct to SB ▒▒▒}
Procedure SBDirectOut(Sample:BYTE);
Begin
SBWrite($10);
SBWrite(Sample);
End;
{▓▓▓▓▓ Entrée/Sortie de samples via DMA ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}
{▒▒▒ SBSetFreq: Règle la fréquence de sampling ▒▒▒}
Procedure SBSetFreq(Freq:WORD);
Begin
SBWrite($40);
SBWrite(256-1000000 div Freq);
End;
{▒▒▒ SBDmaIn: Enregistre un sample via DMA ▒▒▒}
Procedure SBDmaIn(Count:WORD;Address:POINTER);
Begin
DMAInit(SBDma,DMARead,Count,Address);
Dec(Count);
SBDmaDone:=FALSE;
SBWrite($24);
SBWrite(Lo(Count));
SBWrite(Hi(Count));
End;
{▒▒▒ SBDmaOut: Sort un sample via DMA ▒▒▒}
Procedure SBDmaOut(Count:WORD;Address:POINTER);
Begin
DMAInit(SBDma,DMAWrite,Count,Address);
Dec(Count);
SBDmaDone:=FALSE;
SBWrite($14);
SBWrite(Lo(Count));
SBWrite(Hi(Count));
End;
{▒▒▒ SBStopDma: Stoppe le transfert DMA ▒▒▒}
Procedure SBStopDma;
Begin
SBWrite($D0);
End;
{▒▒▒ SBContinueDma: Continue un transfert DMA interrompu ▒▒▒}
Procedure SBContinueDma;
Begin
SBWrite($D4);
End;
{▓▓▓▓▓ Install/Uninstall handler d'irq ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}
{░░░ SBIrqHandler: Handler d'irq ░░░}
Procedure SBIrqHandler; interrupt; assembler;
Asm
mov [SBDmaDone],TRUE
mov dx,[SBPort] {Sert à que dalle mais c'est dans la doc...}
or dl,DSPDataState
in al,dx
mov al,20h
cmp [SBIrq],8
jb @SBLowIrq
out 0a0h,al
@SBLowIrq:
out 020h,al
End;
{▒▒▒ SBInit: Installe le handler d'irq ▒▒▒}
Procedure SBInit;
Begin
If SBIrq<8 then
Begin
GetIntVec(SBIrq+$8,OldHandlerAddr);
SetIntVec(SBIrq+$8,@SBIrqHandler);
Port[$21]:=Port[$21] and (not (1 shl SBIrq));
End
Else
Begin
GetIntVec(SBIrq+$70,OldHandlerAddr);
SetIntVec(SBIrq+$70,@SBIrqHandler);
Port[$A1]:=Port[$A1] and (not (1 shl (SBIrq and 7)));
End;
End;
{▒▒▒ SBDone: UnInstalle le handler d'irq ▒▒▒}
Procedure SBDone;
Begin
If SBIrq<8 then SetIntVec(SBIrq+$8,OldHandlerAddr)
else SetIntVec(SBIrq+$70,OldHandlerAddr);
End;
End.