// This Code is for hardware function demonstration purposes only
// Leipzig 02-19-98 (c) 1998 marian GbR Leipzig

const
  adPlayEnable       = $01;
  adRecEnable        = $02;

  CtrlReg            = $04;
  rateFollows        = $00;
  rate48000          = $01;
  rate44100          = $02;
  rate32000          = $03;
  rateThru           = $04;
  mskRate            = $07;
  IntReset           = $08;
  digRecEnable       = $10;
  digPlayEnable      = $20;
  anlgRecEnable      = $40;
  anlgPlayEnable     = $80;

{ DevGrp^.CardLin^.Control^ = Memory Address of Control Register of FPGA at Card }

function anlg_GetPlayCounter (DevGrp : PDevGroup) : DWORD; register;
 { Return RAM Play Position in Stereo 16 Bit Samples }

 { xxxxxxxx|........|........|........ - x = Bits 5..12 of analog Play RAM Byte Counter at Control Register
   ........|........|........|xxxxxxxx     = after SHR 24 Operation
   ........|........|...xxxxx|xxx.....     = after SHL 5 (phys. Bit0 = log. Bit5) = RAM Byte Counter
   ........|........|.....xxx|xxxxx...     = after SHR 2 (Bytes -> Stereosamples)

   => Counters in Control -> Stereosamplecounter = SHR 21
  }
begin
  Result := DevGrp^.CardLin^.Control^ And $FF000000 shr 21;
end;

function anlg_GetRecordCounter (DevGrp : PDevGroup) : DWORD; register;
 { Return RAM Record Position in Stereo 16 Bit Samples }

 { ........|xxxxxxxx|........|........ - x = Bits 5..12 of analog Record RAM Byte Counters at Control Register
   ........|........|........|xxxxxxxx     = after SHR 16 Operation
   ........|........|...xxxxx|xxx.....     = after SHL 5 (phys. Bit0 = log. Bit5) = RAM Byte Counter
   ........|........|.....xxx|xxxxx...     = after SHR 2 (Bytes -> Stereosamples)

   => Counters in Control -> Stereosamplecounter = SHR 13
  }
begin
  Result := DevGrp^.CardLin^.Control^ And $00FF0000 shr 13;
end;

function dig_GetPlayCounter (DevGrp : PDevGroup) : DWORD; register;
 { Return RAM Play Position in Stereo 32 Bit Samples }

 { ........|........|xxxxxxxx|........ - x = Bits 5..12 of analog Play RAM Byte Counters at Control Register
   ........|........|........|xxxxxxxx     = after SHR 8 Operation
   ........|........|...xxxxx|xxx.....     = after SHL 5 (phys. Bit0 = log. Bit5) = RAM Byte Counter
   ........|........|......xx|xxxxxx..     = after SHR 3 (Bytes -> 32 Bit Stereosamples)

   => Counters in Control -> Stereosamplecounter = SHR 6
  }
begin
  Result := DevGrp^.CardLin^.Control^ And $0000FF00 shr 6;
end;

function dig_GetRecordCounter (DevGrp : PDevGroup) : DWORD; register;
 { Return RAM Play Position in Stereo 32 Bit Samples }

 { ........|........|........|xxxxxxxx - x = Bits 5..12 of analog Play RAM Byte Counters at Control Register
   ........|........|...xxxxx|xxx.....     = after SHL 5 (phys. Bit0 = log. Bit5) = RAM Byte Counter
   ........|........|.......x|xxxxxx..     = after SHR 3 (Bytes -> 32 Bit Stereosamples)

   => Counters in Control -> Stereosamplecounter = SHL 2
  }
begin
  Result := DevGrp^.CardLin^.Control^ And $000000FF shl 2;
end;

procedure EnableRecAndPlay (var DevGrp : TDevGroup);
begin
  with DevGrp, CardLin^ do
  begin
    if GrpTyp = grpAnalog then
    begin
      CtrlStat := CtrlStat And Not anlgPlayEnable And Not anlgRecEnable;
      Control^ := CtrlStat; { Control Register write }
    end;

   { Call depends on Device Type (analog/Digital)}
    procEnableRecAndPlay (@DevGrp);

    if GrpTyp = grpAnalog then
    begin
      CtrlStat := CtrlStat Or anlgPlayEnable Or anlgRecEnable;
      Control^  := CtrlStat; { Control Register write }
    end;
  end;
end;

procedure DisableRecAndPlay (var DevGrp : TDevGroup);
begin
  DevGrp.procDisableRecAndPlay (@DevGrp);
end;

function anlg_EnablePlay (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^, CardLin^ do
  begin
    adRecPlayStat := adRecPlayStat Or adPlayEnable;
    SetParam (DevGrp^, 9, adRecPlayStat, selAdAll);
  end;
end;

function anlg_DisablePlay (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^, CardLin^ do
  begin
    adRecPlayStat := adRecPlayStat And Not adPlayEnable;
    SetParam (DevGrp^, 9, adRecPlayStat, selAdAll);
  end;
end;

function anlg_EnableRecord (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^, CardLin^ do
  begin
    adRecPlayStat := adRecPlayStat Or adRecEnable;
    SetParam (DevGrp^, 9, adRecPlayStat, selAdAll);
  end;
end;

function anlg_DisableRecord (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^, CardLin^ do
  begin
    adRecPlayStat := adRecPlayStat And Not adRecEnable;
    SetParam (DevGrp^, 9, adRecPlayStat, selAdAll);
  end;
end;

function anlg_EnableRecAndPlay (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^, CardLin^ do
  begin
    adRecPlayStat := adRecPlayStat Or adPlayEnable Or adRecEnable;
    SetParam (DevGrp^, 9, adRecPlayStat, selAdAll);
  end;
end;

function anlg_DisableRecAndPlay (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^, CardLin^ do
  begin
    adRecPlayStat := adRecPlayStat And Not adPlayEnable And Not adRecEnable;
    SetParam (DevGrp^, 9, adRecPlayStat, selAdAll);
  end;
end;

function dig_EnablePlay (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^.CardLin^ do
  begin
    CtrlStat := CtrlStat Or digPlayEnable;
    Control^ := CtrlStat;
  end;
end;

function dig_DisablePlay (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^.CardLin^ do
  begin
    CtrlStat := CtrlStat And Not digPlayEnable;
    Control^ := CtrlStat;
  end;
end;

function dig_EnableRecord (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^.CardLin^ do
  begin
    CtrlStat := CtrlStat Or digRecEnable;
    Control^ := CtrlStat;
  end;
end;

function dig_DisableRecord (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^.CardLin^ do
  begin
    CtrlStat := CtrlStat And Not digRecEnable;
    Control^ := CtrlStat;
  end;
end;

function dig_EnableRecAndPlay (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^.CardLin^ do
  begin
    CtrlStat := CtrlStat Or digRecEnable Or digPlayEnable;
    Control^ := CtrlStat;
  end;
end;

function dig_DisableRecAndPlay (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^.CardLin^ do
  begin
    CtrlStat := CtrlStat And Not digRecEnable And Not digPlayEnable;
    Control^ := CtrlStat;
  end;
end;

{ Proc's zum Reseten der Counter der Gerätegruppen }

procedure ResetDevGroup (var DevGrp : TDevGroup);
begin
  DevGrp.procResetDevGroup (@DevGrp);
end;

procedure ResetInpDevs (var DevGrp : TDevGroup);
begin
  DevGrp.procResetInpDevs (@DevGrp);
end;

procedure ResetOutDevs (var DevGrp : TDevGroup);
begin
  DevGrp.procResetOutDevs (@DevGrp);
end;

function anlg_ResetDevGroup (DevGrp : PDevGroup) : DWORD; register;
var
  EnableStat : DWORD;
begin
  with DevGrp^.CardLin^ do
  begin
    EnableStat := CtrlStat And (anlgPlayEnable Or anlgRecEnable);
    CtrlStat   := CtrlStat And Not anlgPlayEnable And Not anlgRecEnable;
    Control^   := CtrlStat;
    CtrlStat   := CtrlStat Or EnableStat;
    Control^   := CtrlStat;
  end;
end;

function anlg_ResetInpDevs (DevGrp : PDevGroup) : DWORD; register;
var
  EnableStat : DWORD;
begin
  with DevGrp^.CardLin^ do
  begin
    EnableStat := CtrlStat And anlgRecEnable;
    CtrlStat   := CtrlStat And Not anlgRecEnable;
    Control^   := CtrlStat;
    CtrlStat   := CtrlStat Or EnableStat;
    Control^   := CtrlStat;
  end;
end;

function anlg_ResetOutDevs (DevGrp : PDevGroup) : DWORD; register;
var
  EnableStat : DWORD;
begin
  with DevGrp^.CardLin^ do
  begin
    EnableStat := CtrlStat And anlgPlayEnable;
    CtrlStat   := CtrlStat And Not anlgPlayEnable;
    Control^   := CtrlStat;
    CtrlStat   := CtrlStat Or EnableStat;
    Control^   := CtrlStat;
  end;
end;

function dig_ResetDevGroup (DevGrp : PDevGroup) : DWORD; register;
var
  EnableStat : DWORD;
begin
  with DevGrp^.CardLin^ do
  begin
    EnableStat := CtrlStat And (digPlayEnable Or digRecEnable);
    CtrlStat   := CtrlStat And Not digPlayEnable And Not digRecEnable;
    Control^   := CtrlStat;
    CtrlStat   := CtrlStat Or EnableStat;
    Control^   := CtrlStat;
  end;
end;

function dig_ResetInpDevs (DevGrp : PDevGroup) : DWORD; register;
var
  EnableStat : DWORD;
begin
  with DevGrp^.CardLin^ do
  begin
    EnableStat := CtrlStat And digRecEnable;
    CtrlStat   := CtrlStat And Not digRecEnable;
    Control^   := CtrlStat;
    CtrlStat   := CtrlStat Or EnableStat;
    Control^   := CtrlStat;
  end;
end;

function dig_ResetOutDevs (DevGrp : PDevGroup) : DWORD; register;
var
  EnableStat : DWORD;
begin
  with DevGrp^.CardLin^ do
  begin
    EnableStat := CtrlStat And digPlayEnable;
    CtrlStat   := CtrlStat And Not digPlayEnable;
    Control^   := CtrlStat;
    CtrlStat   := CtrlStat Or EnableStat;
    Control^   := CtrlStat;
  end;
end;

{ after Initialization Enable all  }

procedure EnableCard (var Crd : TCard);
begin
 { Digital Part is controlled by this flags only (analog part via AD's - therefore don't enable it) }
  with Crd do
  begin
    CtrlStat := rate44100 Or anlgPlayEnable Or anlgRecEnable And Not digPlayEnable And Not digRecEnable;
    Control^ := CtrlStat;
  end;
end;

{ before Shutdown disable all }

procedure DisableCard (var Crd : TCard);
begin
  with Crd do
  begin
    CtrlStat := Not anlgPlayEnable And Not anlgRecEnable And Not digPlayEnable And Not digRecEnable;
    Control^ := CtrlStat;
  end;
end;

{ Fn's to Set the Sample Rate ----------------------------------------------------------------------- }

procedure SetRate (var DevGrp : TDevGroup);
begin
  DevGrp.procSetRate (@DevGrp);
end;

function anlg_SetRate (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^ do
  begin
   { set Mode2 Frequ. Reg. (Important: use THIS call order }
    SetParam (DevGrp^, 22, Rate div 256, selAdAll);
    SetParam (DevGrp^, 23, Rate mod 256, selAdAll);
  end;
end;

function dig_SetRate (DevGrp : PDevGroup) : DWORD; register;
begin
  with DevGrp^, CardLin^ do
  begin
    Case Rate of
      32000 : CtrlStat := CtrlStat And Not mskRate Or rate32000;
      44100 : CtrlStat := CtrlStat And Not mskRate Or rate44100;
      48000 : CtrlStat := CtrlStat And Not mskRate Or rate48000;
    end;
    Control^ := CtrlStat;
  end;
end;


