uses crt,dos;
const voclast:Byte=0;           {last value}
      trigger=5;                {sensitivity}
      finished:Boolean=false;   {finished ?}
var   oldint8:Pointer;          {old IRQ 0 handler}
      Voc:Pointer;              {pointer to sample data in memory}
      VocFile:File;             {Voc file}
      timvalue,                 {Value for timer chip}
      vocpos,                   {current offset in Voc file}
      voclen,                   {length of Voc file}
      Hz:Word;                  {Sample frequency}

Procedure Play;interrupt;assembler;
{plays back Voc in the interrupt}
asm
  mov dx,61h                    {read contents of control port}
  in al,dx
  mov cl,al                     {and store in cl}
  les di,voc                    {load es:di with pointer to sample data}
  inc vocpos                    {increment position by 1}
  mov ax,vocpos                 {load in ax}
  add di,ax                     {and add to memory offset}
  cmp ax,voclen                 {end of sample reached ?}
  jne @ok                       {yes,}
  mov finished,1                  {then set flag}
@ok:
  mov al,es:[di]                {otherwise get value}
  mov bl,al                     {store in bl}
  sub al,voclast                {obtain difference to last value}
  mov voclast,bl                {and record value as last value}
  cmp al,trigger                {distance greater than trigger/pickup ?}
  jg @set                       {then set speaker to high}
  cmp al,-trigger               {distance less than negative trigger/pickup ?}
  jg @end                       {no, then dann finished}
  mov al,cl                     {old contents of control port}
  and al,not 2                  {clear bit 1}
  out dx,al                     {and write}
  jmp @end                      {finished}
@set:
  mov al,cl                     {old contents of control port}
  or al,2                       {set bit 1}
  out dx,al                     {and write}
@end:
  pushf                         {call old handler}
  call [oldint8]
End;

begin
  Assign(VocFile,'sekt.voc');  {open file}
  Reset(VocFile,1);             {reset}
  Voclen:=FileSize(VocFile);    {determine length}
  GetMem(Voc,Voclen);           {allocate corresponding memory}
  BlockRead(VocFile,Voc^,FileSize(VocFile));
                                {read in Voc file (max. 64kB)}
  Close(VocFile);               {and close}
  Hz:=1000000 div               {get sample frequency from file}
    (256-Byte(Ptr(Seg(Voc^),Ofs(Voc^)+$1f)^));

  GetIntVec($8,OldInt8);        {store vector IRQ 0}
  SetIntVec($8,@Play);          {bend/deflect IRQ 0 to handler}

   timvalue := 1193180 DIV Hz;  {calculate timer start from sampling frequency}
  Port[$43]:=$36;               {program this to counter 0}
   Port[$40]:=Lo(timvalue);
   Port[$40]:=Hi(timvalue);

  Repeat Until KeyPressed or finished;  {wait until end or key pressed}

  SetIntVec($8,OldInt8);        {restore vector}
  Port[$43]:=$36;               {reset timer}
   Port[$40]:=0;                {(18.2 Hz)}
   Port[$40]:=0;
End.
