unit modul_itp3;

{$mode objfpc}{$H+}

interface

uses
  SysUtils,
  GlobalConfig,
  GlobalConst,
  Platform,
  GPIO,

  modul_conin,
  modul_image,
  modul_conout;
 





const

  nul = #0;
  xon = #17;
  hardware_reset = #64;

  // Befehlscode fuer ITP3
  ITP3_WHO_AM_I = Byte(01);
  ITP3_OS_MARKER = Byte(02);

  ITP3_CONOUT = Byte(03);
  ITP3_CONST  = Byte(04);
  ITP3_CONIN  = Byte(05);

  ITP3_STD    = Byte(06);
  ITP3_RD_SEC = Byte(07);
  ITP3_WR_SEC = Byte(08);




  // Befehlscode fuer OS_MARKER
  OS_NN      = Byte(00);
  OS_CPM     = Byte(01);
  OS_DOS     = Byte(02);
  OS_WIN     = Byte(03);
  OS_LINUX   = Byte(04);



  // dieser ITP3-Modul ist ein
  // CP/M-Modul !!!
  OS_Vorgabe = Byte(OS_CPM);






type


  Tmod_itp3 = class(TObject)

    constructor Create; overload;
    destructor Destroy; override;

  private

    many_CONST : Word;



    function ITP3_Halbbyte_einlesen : Byte;
    procedure ITP3_Halbbyte_ausgeben(H_Byte : Byte);
    procedure ITP3_PRG_OS_MARKER;
    procedure ITP3_PRG_WHO_AM_I;
    procedure ITP3_PRG_CONOUT;
    procedure ITP3_PRG_CONST;
    procedure ITP3_PRG_CONIN;
    procedure ITP3_PRG_STD;
    procedure ITP3_PRG_RD_SEC;
    procedure ITP3_PRG_WR_SEC;

    procedure ITP3_Server_Abfrage;

  public

    LED_READ_Zaehler, LED_WRITE_Zaehler,
    LED_CONOUT_Zaehler : Integer;

    procedure ITP3_Abfrage_Schleife;
    function ITP3_Byte_einlesen : Byte;
    procedure ITP3_Byte_ausgeben(H_Byte : Byte);

    procedure LED_CONOUT_ein;
    procedure LED_READ_ein;
    procedure LED_WRITE_ein;

  end; // Tmod_itp3 = class(TObject)



var
  mod_itp3 : Tmod_itp3;


implementation



constructor Tmod_itp3.Create;
begin
  inherited Create;

  // alle Datenleitungen auf Eingang schalten
  GPIOFunctionSelect(GPIO_PIN_2,GPIO_FUNCTION_IN);
  GPIOFunctionSelect(GPIO_PIN_3,GPIO_FUNCTION_IN);
  GPIOFunctionSelect(GPIO_PIN_4,GPIO_FUNCTION_IN);
  GPIOFunctionSelect(GPIO_PIN_17,GPIO_FUNCTION_IN);

  // Device Select auf Eingang
  GPIOFunctionSelect(GPIO_PIN_22,GPIO_FUNCTION_IN);

  // DR auf Eingang
  GPIOFunctionSelect(GPIO_PIN_27,GPIO_FUNCTION_IN);

  // LEDs als Ausgang aktivieren
  GPIOFunctionSelect(GPIO_PIN_5,GPIO_FUNCTION_OUT);  // LED_GN
  GPIOFunctionSelect(GPIO_PIN_6,GPIO_FUNCTION_OUT);  // LED_GE
  GPIOFunctionSelect(GPIO_PIN_13,GPIO_FUNCTION_OUT); // LED_RT
  GPIOFunctionSelect(GPIO_PIN_19,GPIO_FUNCTION_OUT); // LED_WS

  // LEDs aus
  GPIOOutputSet(GPIO_PIN_5,GPIO_LEVEL_LOW);   // LED_GN
  GPIOOutputSet(GPIO_PIN_6,GPIO_LEVEL_HIGH);  // LED_GE
  GPIOOutputSet(GPIO_PIN_13,GPIO_LEVEL_LOW);  // LED_RT
  GPIOOutputSet(GPIO_PIN_19,GPIO_LEVEL_LOW);  // LED_WS

  LED_READ_Zaehler:=0;
  LED_WRITE_Zaehler:=0;
  LED_CONOUT_Zaehler:=0;

end; { constructor Tmod_itp3.Create }




procedure Tmod_itp3.LED_CONOUT_ein;
begin

  LED_CONOUT_Zaehler:=10000;
  GPIOOutputSet(GPIO_PIN_19,GPIO_LEVEL_HIGH);

end; { procedure Tmod_itp3.LED_CONOUT_ein }




procedure Tmod_itp3.LED_READ_ein;
begin

  GPIOOutputSet(GPIO_PIN_5,GPIO_LEVEL_HIGH);  // LED_GN
  GPIOOutputSet(GPIO_PIN_6,GPIO_LEVEL_LOW);   // LED_GE
  GPIOOutputSet(GPIO_PIN_13,GPIO_LEVEL_LOW);  // LED_RT

  LED_READ_Zaehler:=10000;

end; { procedure Tmod_itp3.LED_READ_ein }





procedure Tmod_itp3.LED_WRITE_ein;
begin

  GPIOOutputSet(GPIO_PIN_5,GPIO_LEVEL_LOW);
  GPIOOutputSet(GPIO_PIN_6,GPIO_LEVEL_LOW);
  GPIOOutputSet(GPIO_PIN_13,GPIO_LEVEL_HIGH);

  LED_WRITE_Zaehler:=10000;

end; { procedure Tmod_itp3.LED_WRITE_ein }




function Tmod_itp3.ITP3_Halbbyte_einlesen : Byte;
var
  b1 : Byte;
begin

  // warten, solange bis der Server das
  // zweite Halbbyte sendet
  //
  while GPIOInputGet(GPIO_PIN_22) = GPIO_LEVEL_HIGH do begin

  end;


  b1:=%00000000;

  // D0 einlesen
  if GPIOInputGet(GPIO_PIN_2) = GPIO_LEVEL_HIGH then begin
    b1:=b1 or %00000001;
  end;

  // D1 einlesen
  if GPIOInputGet(GPIO_PIN_3) = GPIO_LEVEL_HIGH then begin
    b1:=b1 or %00000010;
  end;


  // D2 einlesen
  if GPIOInputGet(GPIO_PIN_4) = GPIO_LEVEL_HIGH then begin
    b1:=b1 or %00000100;
  end;


  // D3 einlesen
  if GPIOInputGet(GPIO_PIN_17) = GPIO_LEVEL_HIGH then begin
    b1:=b1 or %00001000;
  end;


  // jetzt wird dem Server mitgeteilt,
  // das die Daten uebernommen wurden
  GPIOOutputSet(GPIO_PIN_27,GPIO_LEVEL_LOW);

  // warten solange bis der Server die
  // Bestaetigung angenommen hat

  while GPIOInputGet(GPIO_PIN_22) = GPIO_LEVEL_LOW do begin

  end;


  // DR auf High (Grundeinstellung)
  GPIOOutputSet(GPIO_PIN_27,GPIO_LEVEL_HIGH);

  Result:=b1;

end; { function Tmod_itp3.ITP3_Halbbyte_einlesen }





function Tmod_itp3.ITP3_Byte_einlesen : Byte;
var
  b1 : Byte;
  Result_Byte : Byte;
begin

  // DR auf High (Grundeinstellung)
  GPIOOutputSet(GPIO_PIN_27,GPIO_LEVEL_HIGH);
  // DR auf Ausgang - sendebereit -
  GPIOFunctionSelect(GPIO_PIN_27,GPIO_FUNCTION_OUT);
  // DR auf High (Grundeinstellung)
  GPIOOutputSet(GPIO_PIN_27,GPIO_LEVEL_HIGH);


  Result_Byte:=ITP3_Halbbyte_einlesen;


  b1:=ITP3_Halbbyte_einlesen;

  // DR wieder auf Eingang fuer die anderen Clients
  GPIOFunctionSelect(GPIO_PIN_27,GPIO_FUNCTION_IN);

  b1:= b1 SHL 4;

  Result_Byte:=Result_Byte+b1;

  Result:=Result_Byte;

end; { function Tmod_itp3.ITP3_Byte_einlesen }






procedure Tmod_itp3.ITP3_Halbbyte_ausgeben(H_Byte : Byte);
var
  b1 : Byte;
begin

  // CB

  b1:=H_Byte and %00000001;

  // D0 ausgeben
  if b1=0 then
    GPIOOutputSet(GPIO_PIN_2,GPIO_LEVEL_LOW)
  else
    GPIOOutputSet(GPIO_PIN_2,GPIO_LEVEL_HIGH);



  b1:=H_Byte and %00000010;

  // D1 ausgeben
  if b1=0 then
    GPIOOutputSet(GPIO_PIN_3,GPIO_LEVEL_LOW)
  else
    GPIOOutputSet(GPIO_PIN_3,GPIO_LEVEL_HIGH);


  b1:=H_Byte and %00000100;

  // D2 ausgeben
  if b1=0 then
    GPIOOutputSet(GPIO_PIN_4,GPIO_LEVEL_LOW)
  else
    GPIOOutputSet(GPIO_PIN_4,GPIO_LEVEL_HIGH);


  b1:=H_Byte and %00001000;

  // D3 ausgeben
  if b1=0 then
    GPIOOutputSet(GPIO_PIN_17,GPIO_LEVEL_LOW)
  else
    GPIOOutputSet(GPIO_PIN_17,GPIO_LEVEL_HIGH);


  // jetzt wird dem Server mitgeteilt,
  // das die Daten zur Uebernahme
  // anliegen
  GPIOOutputSet(GPIO_PIN_27,GPIO_LEVEL_LOW);


  // warten solange bis der Server die
  // Bestaetigung angenommen hat
  //
  while GPIOInputGet(GPIO_PIN_22) = GPIO_LEVEL_LOW do begin

  end;

  // DR auf High (Grundeinstellung)
  GPIOOutputSet(GPIO_PIN_27,GPIO_LEVEL_HIGH);


end; { procedure Tmod_itp3.ITP3_Halbbyte_ausgeben }






procedure Tmod_itp3.ITP3_Byte_ausgeben(H_Byte : Byte);
var
  b1 : Byte;

begin

  // DR auf High (Grundeinstellung)
  GPIOOutputSet(GPIO_PIN_27,GPIO_LEVEL_HIGH);
  // DR auf Ausgang - sendebereit -
  GPIOFunctionSelect(GPIO_PIN_27,GPIO_FUNCTION_OUT);
  // DR auf High (Grundeinstellung)
  GPIOOutputSet(GPIO_PIN_27,GPIO_LEVEL_HIGH);


  // CA

  // warten, solange bis der Server das
  // zweite Halbbyte sendet
  //
  while GPIOInputGet(GPIO_PIN_22) = GPIO_LEVEL_HIGH do begin

  end;


  // CB

  // alle Datenleitungen auf Ausgang schalten
  GPIOFunctionSelect(GPIO_PIN_2,GPIO_FUNCTION_OUT);  // D0
  GPIOFunctionSelect(GPIO_PIN_3,GPIO_FUNCTION_OUT);  // D1
  GPIOFunctionSelect(GPIO_PIN_4,GPIO_FUNCTION_OUT);  // D2
  GPIOFunctionSelect(GPIO_PIN_17,GPIO_FUNCTION_OUT); // D3



  b1:=H_Byte and %00001111;
  ITP3_Halbbyte_ausgeben(b1);

  b1:= H_Byte SHR 4;


  // warten, solange bis der Server das
  // untere Halbbyte gelesen hat
  //
  while GPIOInputGet(GPIO_PIN_22) = GPIO_LEVEL_HIGH do begin

  end;


  ITP3_Halbbyte_ausgeben(b1);


  // DR wieder auf Eingang fuer die anderen Clients
  GPIOFunctionSelect(GPIO_PIN_27,GPIO_FUNCTION_IN);


  // alle Datenleitungen auf Eingang schalten
  GPIOFunctionSelect(GPIO_PIN_2,GPIO_FUNCTION_IN);
  GPIOFunctionSelect(GPIO_PIN_3,GPIO_FUNCTION_IN);
  GPIOFunctionSelect(GPIO_PIN_4,GPIO_FUNCTION_IN);
  GPIOFunctionSelect(GPIO_PIN_17,GPIO_FUNCTION_IN);


end; { procedure Tmod_itp3.ITP3_Byte_ausgeben }






// ************************************





procedure Tmod_itp3.ITP3_PRG_OS_MARKER;
begin

  // Ausgabe des OS_MARKER
  // hier OS_Vorgabe = OS_CPM
  ITP3_Byte_ausgeben(OS_Vorgabe);

  many_CONST:=0;

end; { procedure Tmod_itp3.ITP3_PRG_OS_MARKER }






{

  Konfiguration WHO_ARE_YOU - Byte
  D7 - CONOUT
  D6 - CONIN
  D5 - LIST
  D4 - SOUND
  D3 - DIVE
  D2 - READER
  D1 - N.N.
  D0 - N.N.

}
procedure Tmod_itp3.ITP3_PRG_WHO_AM_I;
var
  DATA_Byte : Byte;
begin

  DATA_Byte:=%11001000;

  ITP3_Byte_ausgeben(DATA_Byte);

  many_CONST:=0;

end; { procedure ITP3_PRG_WHO_AM_I }





procedure Tmod_itp3.ITP3_PRG_CONOUT;
var
  DATA_Byte : Byte;
begin

  DATA_Byte:=ITP3_Byte_einlesen;

  mod_conout.Write_Char(DATA_Byte);

  many_CONST:=0;

end; { procedure ITP3_PRG_CONOUT }






procedure Tmod_itp3.ITP3_PRG_CONST;
var
  DATA_Byte : Byte;
begin

  if many_CONST>10 then begin
    sleep(50);
  end;

  DATA_Byte:=mod_conin.CONST_ausgeben;

  ITP3_Byte_ausgeben(DATA_Byte);

  Inc(many_CONST);

end; { procedure Tmod_itp3.ITP3_PRG_CONST }






procedure Tmod_itp3.ITP3_PRG_CONIN;
var
  DATA_Byte : Byte;
begin

  DATA_Byte:=mod_conin.CONIN_ausgeben;

  ITP3_Byte_ausgeben(DATA_Byte);

  many_CONST:=0;

end; { procedure Tmod_itp3.ITP3_PRG_CONIN }





procedure Tmod_itp3.ITP3_PRG_STD;
var
  DATA_Byte : Byte;
  TRACK_L   : Integer;
  V_TRACK, V_SECTOR, V_DISKNO : Integer;
begin

 // mod_conout.Write_String('ITP3_PRG_STD...');

  // SECTOR
  DATA_Byte:=ITP3_Byte_einlesen;
  V_SECTOR:=DATA_Byte;

  // TRACK_L
  DATA_Byte:=ITP3_Byte_einlesen;
  TRACK_L:=DATA_Byte;

  // TRACK_H
  DATA_Byte:=ITP3_Byte_einlesen;
  V_TRACK:=DATA_Byte*256;
  V_TRACK:=V_TRACK+TRACK_L;

  // DISKNO wird derzeit ignoriert
  DATA_Byte:=ITP3_Byte_einlesen;
  V_DISKNO:=DATA_Byte;

  mod_image.Spur_und_Sektor_in_Datei_Zeiger(V_TRACK, V_SECTOR, V_DISKNO);

  many_CONST:=0;

end; { procedure Tmod_itp3.ITP3_PRG_STD }





procedure Tmod_itp3.ITP3_PRG_RD_SEC;

begin

  mod_image.Read_IMAGE_Sektor;

  many_CONST:=0;

end; { procedure Tmod_itp3.ITP3_PRG_RD_SEC }






procedure Tmod_itp3.ITP3_PRG_WR_SEC;

begin

  mod_image.Write_IMAGE_Sektor;

  many_CONST:=0;

end; { procedure Tmod_itp3.ITP3_PRG_WR_SEC }




// ************************************



procedure Tmod_itp3.ITP3_Server_Abfrage;
var
  CODE_Byte : Byte;
begin

  // Abfrage DS auf LOW
  if GPIOInputGet(GPIO_PIN_22) = GPIO_LEVEL_LOW then begin

    CODE_Byte:=ITP3_Byte_einlesen;

    case CODE_Byte of

      ITP3_OS_MARKER : ITP3_PRG_OS_MARKER;

      ITP3_WHO_AM_I : ITP3_PRG_WHO_AM_I;

      ITP3_CONOUT : ITP3_PRG_CONOUT;

      ITP3_CONST  : ITP3_PRG_CONST;

      ITP3_CONIN  : ITP3_PRG_CONIN;

      ITP3_STD    : ITP3_PRG_STD;

      ITP3_RD_SEC : ITP3_PRG_RD_SEC;

      ITP3_WR_SEC : ITP3_PRG_WR_SEC;

    end; { case CODE_Byte of }


  end; { if GPIOInputGet(GPIO_PIN_22) }



end; { procedure Tmod_itp3.ITP3_Server_Abfrage }






procedure Tmod_itp3.ITP3_Abfrage_Schleife;
begin

  many_CONST:=0;

  while true do begin

    mod_itp3.ITP3_Server_Abfrage;

    if mod_conout.Cursor_is_on<>Cursor_to_on then begin
      mod_conout.Kursor_umschalten;
    end; { if Cursor_is_on<>Cursor_to_on then }


    if LED_READ_Zaehler>0 then begin

      if LED_READ_Zaehler<30 then begin

        GPIOOutputSet(GPIO_PIN_5,GPIO_LEVEL_LOW);
        GPIOOutputSet(GPIO_PIN_6,GPIO_LEVEL_HIGH);
        GPIOOutputSet(GPIO_PIN_13,GPIO_LEVEL_LOW);

      end; { if LED_READ_Zaehler<3 then }

      DEC(LED_READ_Zaehler);

    end; { if LED_READ_Zaehler>0 then }



    if LED_WRITE_Zaehler>0 then begin

      if LED_WRITE_Zaehler<30 then begin

        GPIOOutputSet(GPIO_PIN_5,GPIO_LEVEL_LOW);
        GPIOOutputSet(GPIO_PIN_6,GPIO_LEVEL_HIGH);
        GPIOOutputSet(GPIO_PIN_13,GPIO_LEVEL_LOW);

      end; { if LED_WRITE_Zaehler<3 then }

      DEC(LED_WRITE_Zaehler);

    end; { if LED_WRITE_Zaehler>0 then }



    if LED_CONOUT_Zaehler>0 then begin

      if LED_CONOUT_Zaehler<30 then begin

        GPIOOutputSet(GPIO_PIN_19,GPIO_LEVEL_LOW);

      end; { if LED_CONOUT_Zaehler<3 then }

      DEC(LED_CONOUT_Zaehler);

    end; { if LED_CONOUT_Zaehler>0 then }



  end; { while true do }

end; { procedure Tmod_itp3.ITP3_Abfrage_Schleife }






destructor Tmod_itp3.Destroy;
begin

  inherited Destroy;
end; { destructor Tmod_itp3.Destroy }





end.

