uses crt, l154pas, graph;

label StartLabel, StartLabel1;

{ объявление переменных }
var
  x, y, ZeroLine, Zoom 	: INTEGER;
  Pixel, StartMode      : INTEGER;

  Rate, Channel, NKadr 	: WORD;
  Usil, Counter, dmm	: WORD;
  MultiChannels, i	: WORD;
  Nchannel              : WORD;
  Segment               : WORD;

  key                   : CHAR;

  Ch			: ARRAY[0..15] OF WORD;
  DemoName              : ARRAY[0..10] OF STRING;
  UsilIndex             : ARRAY[0..2] OF WORD;

  ArrayPtr		: POINTER;

{*****************************************************}
{ драйвер обработчик прерывания IRQ                  *}
{*****************************************************}
procedure IrqHandler; interrupt;
begin
{ введем один отсчет }
Pixel:=Sample;

{ увеличим номер выводимого отсчета на единицу		}
Inc(Counter);

{ если перешли через границу экрана, то начнем сначала	}
if(Counter > Nkadr)
  then begin ClearDevice; Counter:=0; MoveTo(0, ZeroLine+(Pixel) div Zoom +20); end;

{ нарисуем отрезок прямой на экране до текущей точки	}
LineTo(Counter, ZeroLine+(Pixel) div Zoom+20);

{ сбросим контроллер прерываний				}
port[$20]:=$20;
end;

{ запись слова по прямому адресу в памяти		}
procedure MemoryWrite(offset : WORD; value : INTEGER);
begin
memw[Segment : offset*2]:=value;
end;

{ чтение слова по прямому адресу из памяти		}
function MemoryRead(offset : WORD) : WORD;
begin
MemoryRead:= memw[Segment : offset*2];
end;

{ процедура рисования графика				}
procedure DrawCurve;
begin
    Zoom:=2048 div (350 div Nchannel);
    ClearDevice;
    ZeroLine:=(350 div Nchannel) div 2;
    for x:=0 to Nchannel-1 do begin
      Pixel:=memw[$9000:x*2];
      MoveTo( 0, ZeroLine+(Pixel) div Zoom+20);
      for y:=1 to 639 do begin
        Pixel:=memw[$9000:((y*Nchannel)+x)*2];
        LineTo( y, ZeroLine+(Pixel) div Zoom+20);
      end;
      ZeroLine:=ZeroLine + (350 div Nchannel);
    end;
end;

{ ОСНОВНАЯ ПОЦЕДУРА     }
{$F+}
begin

 StartLabel1:

  Usil:=0;
  SetBaseAddress($300);		{ установим базовый адрес 300H	}
  if(Plata_Test = 1) then begin writeln('No Board Detected'); exit; end;
  Intr_Setup(0);

  { введем номер демонстрационного режима }
  DemoName[0]:='SAMPLE      -> 0';
  DemoName[1]:='ADCHAN      -> 1';
  DemoName[2]:='STREAM      -> 2';
  DemoName[3]:='SOFT        -> 3';
  DemoName[4]:='IRQ STREAM  -> 4';
  DemoName[5]:='OUT DA      -> 5';
  DemoName[6]:='DA STREAM   -> 6';

  ClrScr;
  for i:=0 to 6 do
    begin
     gotoxy(30, i+6);
     write(DemoName[i]);
    end;
  gotoxy(30, i+8);
  write('Press Demo Mode :');
  key:=readkey;
  if((key < '0') OR (key > '6')) then exit;

  Segment:=$9000;              { смещение буфера данных в памяти      }
  Usil:=0;                     { диапазон 5.12 В                      }

  UsilIndex[0]:=$C0;
  UsilIndex[1]:=$80;
  UsilIndex[2]:=$40;

  directvideo:=FALSE;
  for x:=0 to 15 do ch[x]:=x OR UsilIndex[Usil];
  x:=EGA; y:=EGAHi;
  initgraph(x,y,'');
  Channel:=0 OR UsilIndex[Usil];{ номер канала для одноканального ввода	}
  MultiChannels:=4;		{ число каналов для многоканального ввода }
  Nkadr:=640;                   { число вводимых кадров  		}
  Rate:=60;                     { интервал между кадрами в мкс.		}
  dmm:=0;                       { однократный ввод по каналу ПДП 	}
  StartMode:=1;                 { синхронизация ввода от первого 	}
  ArrayPtr:=Ptr($9000,0);	{ адрес буфера в памяти			}

 StartLabel:

  case key of
    '0':
    	{****************************************************************
		   режим однократного ввода при помощи функции SAMPLE
		   Вызываемые функции : SAMPLE, SETCHANNEL		*}
         begin
         Nchannel:=1;
         SetChannel(Channel);
         for i:=0 to Nkadr do  MemoryWrite(i, Sample);
         DrawCurve;
         end;

    '1':
	 {*	   режим однократного ввода при помощи  функции ADCHAN
		   Вызываемые функции : ADCHAN             		*}
         begin
         Nchannel:=1;
         for i:=0 to Nkadr do  MemoryWrite(i, AdChan(Channel));
         DrawCurve;
         end;

    '2':
	 {*	   режим одноканального ввода в программном режиме
		   при помощи функции STREAM.
		   Вызываемые функции : STREAM.
		   Предельная частота ввода 100 кГц (10 мкс).       	*}
         begin
         Nchannel:=1;
         STREAM(ArrayPtr, Nkadr, Channel, Rate);
         DrawCurve;
         end;

    '3':
	 {*	   режим многоканального ввода в программном режиме
		   при помощи функции SOFT.
		   Вызываемые функции : SOFT
		   Предельная частота ввода 100 кГц (10 мкс) на канал   *}
         begin
         Nchannel:=MultiChannels;
         SOFT(ArrayPtr, Nkadr, addr(Ch), Nchannel, Rate);
         DrawCurve;
         end;


    '4':
	 {*	   режим генерации прерываний после преобразования с АЦП:
		   драйвер - обработчик прерывания отображает данные,
		   вводимые с канала  Channel
		   Вызываемые функции : INIT_INTR, STOP_INTR.		*}
         begin
         SetChannel(Channel);
         Counter:=Nkadr+1;
         Zoom:=2048 div 350;
         ZeroLine:=350 div 2;
         INITINTR(100, 10, ADDR(IrqHandler));
         while keypressed = FALSE do;
         STOP_INTR;
         end;

    '5':
	 {*	   режим вывода на ЦАП пилообразного сигнала
		   при помощи функции OUTDA.
		   Вызываемые функции : OUTDA.				*}
         begin
         ClearDevice;
         gotoxy(25, 12);
         write('Out Triangle On DA in progress...');
         while KeyPressed = FALSE do for i:=0 to 4095 do OutDa(i);
         end;

    '6':
	 {*	   режим вывода на ЦАП пилообразного сигнала
		   при помощи функции OUTDAARRAY.
		   Вызываемые функции : OUTDAARRAY.			*}
         begin
         ClearDevice;
         gotoxy(25, 12);
         write('Out Triangle On DA in progress...');
         for i:=0 to 4095 do MemoryWrite(i, i);
         while KeyPressed = FALSE do OUTDAARRAY(ArrayPtr, Rate, 4095);
         end;

  end;

 if (keypressed = FALSE) then goto StartLabel;
 key:=readkey;
 if(key <> #27) then begin CloseGraph; goto StartLabel1; end;

CloseGraph;
end.
