unit Main;

{ Delphi (V.1) main unit source file of the UPIO Application}
{ Copyright (1998) Dimitriadis D. Aggelos}

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, Menus, LPTs, ExtCtrls, StdCtrls, Buttons, VBXCtrl, Switch,
  FileCtrl;

type
  TMainForm = class(TForm)
    Menu1: TMainMenu;
    Load1: TMenuItem;
    Save1: TMenuItem;
    SaveAs1: TMenuItem;
    Exit1: TMenuItem;
    prog1: TMenuItem;
    New_Prog1: TMenuItem;
    Test1: TMenuItem;
    Help1: TMenuItem;
    About1: TMenuItem;
    HelpContents1: TMenuItem;
    File1: TMenuItem;
    N2: TMenuItem;
    N4: TMenuItem;
    Timer1: TTimer;
    Lpt_Com: TLpt_Control;
    BUT_EXE: TBitBtn;
    BUT_STOP: TBitBtn;
    Step: TBitBtn;
    Bevel1: TBevel;
    Label1: TLabel;
    BUT_EMER: TBitBtn;
    Label2: TLabel;
    Bevel3: TBevel;
    Bevel4: TBevel;
    LIN1: TSpeedButton;
    LIN2: TSpeedButton;
    LIN3: TSpeedButton;
    LIN4: TSpeedButton;
    LIN5: TSpeedButton;
    LIN6: TSpeedButton;
    LIN7: TSpeedButton;
    LIN8: TSpeedButton;
    LO1: TSpeedButton;
    LO2: TSpeedButton;
    LO3: TSpeedButton;
    LO4: TSpeedButton;
    LO5: TSpeedButton;
    LO6: TSpeedButton;
    LO7: TSpeedButton;
    LO8: TSpeedButton;
    Label3: TLabel;
    Label4: TLabel;
    Panel1: TPanel;
    OpenDialog1: TOpenDialog;
    Preferences1: TMenuItem;
    In_status1: TMenuItem;
    Out_Status1: TMenuItem;
    ParallelPort1: TMenuItem;
    Prog_Palette: TGroupBox;
    But_Next_Instr: TButton;
    But_Prev_Instr: TButton;
    But_New_Instr: TButton;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    CheckBox6: TCheckBox;
    CheckBox7: TCheckBox;
    CheckBox8: TCheckBox;
    CheckBox9: TCheckBox;
    CheckBox10: TCheckBox;
    Bevel5: TBevel;
    Bevel6: TBevel;
    Bevel7: TBevel;
    H0: TCheckBox;
    H1: TCheckBox;
    H2: TCheckBox;
    H3: TCheckBox;
    H4: TCheckBox;
    H5: TCheckBox;
    H6: TCheckBox;
    H7: TCheckBox;
    Edit1: TEdit;
    CheckBox19: TCheckBox;
    Label5: TLabel;
    L0: TCheckBox;
    L1: TCheckBox;
    L2: TCheckBox;
    L3: TCheckBox;
    L4: TCheckBox;
    L5: TCheckBox;
    L6: TCheckBox;
    L7: TCheckBox;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Bevel8: TBevel;
    Bevel9: TBevel;
    Label10: TLabel;
    New1: TMenuItem;
    But_Save: TButton;
    But_Close: TButton;
    Pref1: TGroupBox;
    Edit2: TEdit;
    But_Set_Conf: TBitBtn;
    But_Set_Abort: TBitBtn;
    Bevel10: TBevel;
    Bevel11: TBevel;
    Undo_Item1: TMenuItem;
    Del_Item1: TMenuItem;
    Bevel2: TBevel;
    Bevel12: TBevel;
    Bevel13: TBevel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label24: TLabel;
    Label25: TLabel;
    Label26: TLabel;
    Close1: TMenuItem;
    Stop1: TMenuItem;
    EnableHints1: TMenuItem;
    On_Off1: TBiSwitch;
    Bevel14: TBevel;
    Label27: TLabel;
    N1: TMenuItem;
    N3: TMenuItem;
    Hold: TCheckBox;
    procedure About1Click(Sender: TObject);
    procedure Load1Click(Sender: TObject);
    procedure AppIdle(Sender: TObject; var Done: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure BUT_EXEClick(Sender: TObject);
    procedure BUT_STOPClick(Sender: TObject);
    procedure New_Prog1Click(Sender: TObject);
    procedure New1Click(Sender: TObject);
    procedure But_CloseClick(Sender: TObject);
    procedure SaveAs1Click(Sender: TObject);
    procedure BUT_EMERClick(Sender: TObject);
    procedure StepClick(Sender: TObject);
    procedure ParallelPort1Click(Sender: TObject);
    procedure In_status1Click(Sender: TObject);
    procedure But_Set_ConfClick(Sender: TObject);
    procedure But_Set_AbortClick(Sender: TObject);
    procedure Out_Status1Click(Sender: TObject);
    procedure Save1Click(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure But_Next_InstrClick(Sender: TObject);
    procedure But_Prev_InstrClick(Sender: TObject);
    procedure But_New_InstrClick(Sender: TObject);
    procedure Undo_Item1Click(Sender: TObject);
    procedure Del_Item1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Exit1Click(Sender: TObject);
    procedure HelpContents1Click(Sender: TObject);
    procedure EnableHints1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);

  private
    { Private declarations}
    procedure Clear_Record;
    procedure Update_Session;
    procedure Update_Prog_Window;
    procedure Step_Program;
    procedure Stop_Program;
    procedure Load_Instr;
    procedure Store_Instr;
    procedure Execute_Instr;
    procedure Led_Panel_In;
    procedure Led_Panel_Out;
    procedure Load_Output;
    function Load_Input :Byte;
    procedure Exit_Upio_Environment;
    procedure Change_File;

  public
    { Public declarations }
  end;

Type
    Command_Line = record
                 Input_En         :Boolean;
                 Input_Word       :Byte;
                 Out_En           :Boolean;
                 Out_Word_Raise   :Byte;
                 Out_Word_Fall    :Byte;
                 Hold_Out         :Boolean;
                 Timer_En         :Boolean;
                 Timer_Delay      :Integer;
    end;

Const
     Line_Limit = 256;

var
  MainForm          :TMainForm;
  Execution_Status, File_Opened, Modified,
  Lpt_Conf, Input_Conf, Test_Mode, Output_Conf,
  Output_Flow, New_Program
                    :Boolean;
  In_List, Hold_List:Array[1..Line_Limit]of Boolean;
  In_Word_List      :Array[1..Line_Limit]of Byte;
  Count, Count_Fast
                    :Longint;
  FCode_Exe         :File of Command_Line;
  Instr, Instr_Buffer
                    :Command_Line;
  Previous_Output, Input_Buffer, Input_Idle,
  Out_Protection, Input_Check
                    :Byte;
  Info_Tag1, Info_Tag2
                    :string;

implementation

USES ABOUT;

{$R *.DFM}

procedure TMainForm.About1Click(Sender: TObject);
begin
AboutBox.Show;
end;

procedure TMainForm.Load1Click(Sender: TObject);
begin
With OpenDialog1 do
     begin
          Title:='Load Program to Execute';
          if execute then
             begin
                  if fileexists(filename) then
                     begin
                          assignfile(FCode_Exe,filename);
                          reset(FCode_Exe);
                          Count:=0;
                          seek(FCode_Exe,Count);
                          if not(eof(FCode_Exe))then
                             begin
                                  read(FCode_Exe,Instr);
                                  seek(FCode_Exe,Count);
                                  Input_Idle:=Instr.Input_Word;
                                  Out_Protection:=Instr.Out_Word_Fall;
                                  Count:=1;
                                  seek(FCode_Exe,Count);
                                  if eof(FCode_Exe)then Count:=0;
                                  seek(FCode_Exe,Count);
                                  case Instr.Timer_Delay of
                                       1:
                                         begin
                                              Lpt_Com.Comm_Port:='LPT1';
                                              Lpt_Com.Comm_Addr:=889;
                                              Lpt_Com.Open_Port;
                                              Lpt_Com.Tag:=1;
                                         end;
                                       2:
                                         begin
                                              Lpt_Com.Comm_Port:='LPT2';
                                              Lpt_Com.Comm_Addr:=633;
                                              Lpt_Com.Open_Port;
                                              Lpt_Com.Tag:=1;
                                         end;
                                       3:
                                         begin
                                              Lpt_Com.Comm_Port:='LPT3';
                                              Lpt_Com.Comm_Addr:=377;
                                              Lpt_Com.Open_Port;
                                              Lpt_Com.Tag:=1;
                                         end;
                                       else
                                           begin
                                                messagedlg('Communications Port statement is missing',mterror,[mbok],0);
                                                Count:=0;
                                           end;
                                  end;
                             end
                          else messagedlg('File is Empty',mtwarning,[mbok],0);
                          Lpt_Com.Out_Status:=0;
                          File_Opened:=true;
                          if Lpt_Com.Tag=1 then
                             begin
                                  Lpt_Com.Out_Status:=(Lpt_Com.Out_Status)or(4);
                                  Lpt_Com.Build_Out;
                             end;
                          panel1.caption:='Program is loaded';
                     end
                  else messagedlg('File Not Found',mtinformation,[mbok],0);
             end;
     end;
Update_Session;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
Count:=0;
Count_Fast:=0;
Previous_Output:=0;
File_Opened:=false;
New_Program:=false;
Execution_Status:=false;
Lpt_Conf:=false;
Input_Conf:=false;
Output_Conf:=false;
Test_Mode:=false;
Output_Flow:=false;
panel1.caption:='No Program. Wait for Instruction...';
Update_Session;
Application.OnIdle:=AppIdle;
end;

procedure TMainForm.AppIdle(Sender: TObject; var Done: Boolean);
begin
Done:=false;
if Output_Flow then Step_Program;
if Execution_Status then
   begin
        Count_Fast:=Count_Fast+1;
        if (Count_Fast>(filesize(FCode_Exe)-1))then Count_Fast:=0;
        if (In_List[Count_Fast])then
           begin
                seek(FCode_Exe,Count_Fast);
                read(FCode_Exe,Instr_Buffer);
                seek(FCode_Exe,Count_Fast);
                Input_Check:=Load_Input;
                Led_Panel_In;
                if (Input_Check=In_Word_List[Count_Fast])then
                   begin
                        if (Hold_List[Count_Fast])then
                           begin
                                Previous_Output:=(Previous_Output)or(Instr_Buffer.Out_Word_Raise);
                                Previous_Output:=(Previous_Output)and(Instr_Buffer.Out_Word_Fall);
                                Lpt_Com.Byte_Out:=Previous_Output;
                                Lpt_Com.Send_Byte_To_Port;
                           end;
                   end
                else
                    begin
                         if not(Hold_List[Count_Fast])then
                            begin
                                 Previous_Output:=(Previous_Output)and(not(Instr_Buffer.Out_Word_Raise));
                                 Previous_Output:=(Previous_Output)or(not(Instr_Buffer.Out_Word_Fall));
                                 Lpt_Com.Byte_Out:=Previous_Output;
                                 Lpt_Com.Send_Byte_To_Port;
                            end;
                    end;
           end;
   end;
end;

procedure TMainForm.BUT_EXEClick(Sender: TObject);
Var
   I :Longint;
begin
     Timer1.enabled:=false;
     Test_Mode:=false;
     if But_Exe.caption='Start' then
        begin
             But_Exe.caption:='Pause';
             Execution_Status:=true;
             Output_Flow:=true;
             Count:=1;
             On_Off1.caption:='On';
             On_Off1.pon:=true;
             Panel1.caption:='Program is running';
             for I:=1 to (filesize(FCode_Exe)-1)do
                 begin
                      seek(FCode_Exe,I);
                      read(FCode_Exe,Instr);
                      seek(FCode_Exe,I);
                      In_List[I]:=Instr.Input_En;
                      Hold_List[I]:=Instr.Hold_Out;
                      In_Word_List[I]:=Instr.Input_Word;
                 end;
        end
     else
         begin
              But_Exe.caption:='Start';
              Execution_Status:=false;
              Output_Flow:=false;
              Count_Fast:=0;
              On_Off1.caption:='Off';
              On_Off1.pon:=false;
              Panel1.caption:='Program is paused';
         end;
     Update_Session;
end;

procedure TMainForm.BUT_STOPClick(Sender: TObject);
begin
Timer1.enabled:=false;
Stop_Program;
Update_Session;
end;

procedure TMainForm.New_Prog1Click(Sender: TObject);
begin
Prog_Palette.show;
Info_Tag2:=panel1.caption;
Count:=1;
seek(FCode_Exe,Count);
if not(eof(FCode_Exe))then read(FCode_Exe,Instr)
else
    begin
         Count:=0;
         Clear_Record;
    end;
seek(FCode_Exe,Count);
Update_Prog_Window;
Update_Session;
end;

procedure TMainForm.New1Click(Sender: TObject);
begin
assignfile(FCode_Exe,'Untitled.pio');
rewrite(FCode_Exe);
File_Opened:=true;
New_Program:=true;
Count:=0;
seek(FCode_Exe,Count);
Update_Session;
end;

procedure TMainForm.But_CloseClick(Sender: TObject);
begin
Prog_Palette.hide;
panel1.caption:=Info_Tag2;
Update_Session;
end;

procedure TMainForm.SaveAs1Click(Sender: TObject);
begin
Change_File;
end;


procedure TMainForm.Update_Session;
begin
{Enable conditions if a file is opened}
if File_Opened then
   begin
        Save1.enabled:=(Modified)and(not(Pref1.visible));
        New_Prog1.enabled:=(not(Prog_Palette.visible))and(filesize(FCode_Exe)>0);
        Undo_Item1.enabled:=(filesize(FCode_Exe)>0)and(Modified);
        Del_Item1.enabled:=(filesize(FCode_Exe)>2)and(Prog_Palette.visible)and(not(Modified));
        Test1.enabled:=(not(Modified))and(filesize(FCode_Exe)>1)and(not(Prog_Palette.visible));
        But_Exe.enabled:=(filesize(FCode_Exe)>1);
        Step.enabled:=not(Execution_Status)and(filesize(FCode_Exe)>1);
        But_Prev_Instr.enabled:=(not(Modified))and(Count>1)and(not(Pref1.visible));
        But_Next_Instr.enabled:=(not(Modified))and(Count<filesize(FCode_Exe)-1)and(not(Pref1.visible));
   end
else
    begin
         Save1.enabled:=false;
         New_Prog1.enabled:=false;
         Undo_Item1.enabled:=false;
         Del_Item1.enabled:=false;
         Test1.enabled:=false;
         But_Exe.enabled:=false;
         Step.enabled:=false;
         But_Prev_Instr.enabled:=false;
         But_Next_Instr.enabled:=false;
         Prog_Palette.Hide;
    end;
if (Lpt_Com.tag=1)then Stop1.enabled:=true
else Stop1.enabled:=false;
{Menu update}
File1.enabled:=not(Execution_Status);
Prog1.enabled:=not(Execution_Status);
Help1.enabled:=not(Execution_Status);
{File menu update}
New1.enabled:=not(File_Opened);
Load1.enabled:=not(File_Opened);
Close1.enabled:=(File_Opened);
SaveAs1.enabled:=(File_Opened);
{Configuration menu update}
preferences1.enabled:=(File_Opened)and(not(Modified));
{Control buttons update}
But_Stop.enabled:=(File_Opened);
But_Emer.enabled:=(File_Opened);
On_Off1.visible:=But_Exe.enabled;
{Programming buttons update}
But_New_Instr.enabled:=(not(Modified))and(not(Pref1.visible));
But_Save.enabled:=Save1.enabled;
But_Close.enabled:=(not(Modified))and(not(Pref1.visible));
{End of Update}
end;

procedure TMainForm.Stop_Program;
begin
if New_Program then Change_File;
closefile(FCode_Exe);
Lpt_Com.Close_Port;
File_Opened:=false;
New_Program:=false;
Lpt_Com.Tag:=0;
Execution_Status:=false;
Output_Flow:=false;
Test_Mode:=false;
Previous_Output:=0;
Count:=0;
But_Exe.caption:='Start';
On_Off1.caption:='Off';
On_Off1.pon:=false;
panel1.caption:='No Program. Wait for Instruction...';
end;

procedure TMainForm.Load_Output;
Var
   Buffer :Byte;
begin
Buffer:=(Instr.Out_Word_Raise)or(Previous_Output);
Buffer:=(Buffer)and(Instr.Out_Word_Fall);
Previous_Output:=Buffer;
Lpt_Com.Byte_Out:=Buffer;
Lpt_Com.Send_Byte_To_Port;
end;

procedure TMainForm.BUT_EMERClick(Sender: TObject);
begin
Timer1.enabled:=false;
Lpt_Com.Byte_Out:=Out_Protection;
Lpt_Com.Send_Byte_To_Port;
Stop_Program;
Update_Session;
end;

procedure TMainForm.StepClick(Sender: TObject);
begin
Test_Mode:=true;
panel1.caption:='Step in line  '+inttostr(Count);
Step_Program;
led_panel_Out;
end;

procedure TMainform.Change_File;
Const
     Replace_Message = ' already exists. Replace existing file ?';
Var
   Previous_Name    :string;
begin
with opendialog1 do
     begin
          title:='Save Program as...';
          if New_Program then Previous_Name:='Untitled.pio'
          else Previous_Name:=filename;
          if execute then
             begin
                  if ((modified)and(Count>0)) then Store_Instr;
                  if (Count>0)then Count:=1
                  else Count:=0;
                  closefile(FCode_Exe);
                  if not(renamefile(Previous_Name,filename)) then
                     begin
                          if messagedlg(filename+Replace_Message,mtwarning,[mbyes,mbno],0)=mryes then
                             begin
                                  if (Previous_Name <> filename)then
                                     begin
                                          deletefile(filename);
                                          renamefile(Previous_Name,filename);
                                     end;
                             end;
                     end;
                  assignfile(FCode_Exe,filename);
                  reset(FCode_Exe);
                  seek(FCode_Exe,Count);
                  Update_Session;
             end;
     end;
end;

procedure TMainform.Led_Panel_In;
begin
if ((Input_Check)and(1)=(1))then Lin1.enabled:=true
else Lin1.enabled:=false;
if ((Input_Check)and(2)=(2))then Lin2.enabled:=true
else Lin2.enabled:=false;
if ((Input_Check)and(4)=(4))then Lin3.enabled:=true
else Lin3.enabled:=false;
if ((Input_Check)and(8)=(8))then Lin4.enabled:=true
else Lin4.enabled:=false;
if ((Input_Check)and(16)=(16))then Lin5.enabled:=true
else Lin5.enabled:=false;
if ((Input_Check)and(32)=(32))then Lin6.enabled:=true
else Lin6.enabled:=false;
if ((Input_Check)and(64)=(64))then Lin7.enabled:=true
else Lin7.enabled:=false;
if ((Input_Check)and(128)=(128))then Lin8.enabled:=true
else Lin8.enabled:=false;
end;

procedure TMainform.Led_Panel_Out;
begin
if ((Lpt_Com.Byte_Out)and(1)=(1))then Lo1.enabled:=true
else Lo1.enabled:=false;
if ((Lpt_Com.Byte_Out)and(2)=(2))then Lo2.enabled:=true
else Lo2.enabled:=false;
if ((Lpt_Com.Byte_Out)and(4)=(4))then Lo3.enabled:=true
else Lo3.enabled:=false;
if ((Lpt_Com.Byte_Out)and(8)=(8))then Lo4.enabled:=true
else Lo4.enabled:=false;
if ((Lpt_Com.Byte_Out)and(16)=(16))then Lo5.enabled:=true
else Lo5.enabled:=false;
if ((Lpt_Com.Byte_Out)and(32)=(32))then Lo6.enabled:=true
else Lo6.enabled:=false;
if ((Lpt_Com.Byte_Out)and(64)=(64))then Lo7.enabled:=true
else Lo7.enabled:=false;
if ((Lpt_Com.Byte_Out)and(128)=(128))then Lo8.enabled:=true
else Lo8.enabled:=false;
end;

procedure TMainform.Clear_Record;
begin
with Instr do
     begin
          Input_En:=false;
          Input_Word:=0;
          Out_En:=false;
          Out_Word_Raise:=0;
          Out_Word_Fall:=255;
          Hold_Out:=false;
          Timer_En:=false;
          Timer_Delay:=0;
     end;
end;

procedure TMainForm.Step_Program;
begin
if (Count>filesize(FCode_Exe)-1)then Count:=1;
Load_Instr;
Execute_Instr;
Count:=Count+1;
led_panel_Out;
end;

function TMainForm.Load_Input :Byte;
Var
   Local_Buffer1, Local_Buffer2 :Byte;
begin
Lpt_Com.Out_Status:=(Lpt_Com.Out_Status)or(4);
Lpt_Com.Build_Out;
Lpt_Com.Receive_Port;
Local_Buffer1:=Lpt_Com.Data_In;
Local_Buffer1:=(Local_Buffer1)and(15);
Lpt_Com.Out_Status:=(Lpt_Com.Out_Status)and(251);
Lpt_Com.Build_Out;
Lpt_Com.Receive_Port;
Local_Buffer2:=(Lpt_Com.Data_In)shl(4);
Local_Buffer2:=(Local_Buffer2)and(240);
Local_Buffer1:=(Local_Buffer1)or(Local_Buffer2);
Load_Input:=(Local_Buffer1)xor(Input_Idle);
end;

procedure TMainForm.Load_Instr;
begin
seek(FCode_Exe,Count);
read(FCode_Exe,Instr);
seek(FCode_Exe,Count);
end;

procedure TMainForm.Execute_Instr;
begin
if Instr.Out_En then Load_Output;
if ((Instr.Timer_En)and(not(Test_Mode))) then
   begin
        Timer1.interval:=Instr.Timer_Delay;
        Output_Flow:=false;
        Timer1.enabled:=true;
   end;
end;

procedure TMainForm.ParallelPort1Click(Sender: TObject);
begin
Info_Tag1:=panel1.caption;
panel1.caption:='Select the LPT port to be used';
Lpt_Conf:=true;
Pref1.show;
edit2.text:=Lpt_Com.Comm_Port;
activecontrol:=edit2;
Update_Session;
end;

procedure TMainForm.In_status1Click(Sender: TObject);
begin
Info_Tag1:=panel1.caption;
panel1.caption:='Define Input "Idle State" value';
Input_Conf:=true;
Pref1.show;
edit2.text:=inttostr(Input_Idle);
activecontrol:=edit2;
Update_Session;
end;

procedure TMainForm.But_Set_ConfClick(Sender: TObject);
Var
   I :Integer;
begin
I:=Count;
Count:=0;
if Lpt_Conf then
   begin
        Lpt_Conf:=false;
        if edit2.text='LPT1' then
           begin
                Lpt_Com.Comm_Port:=edit2.text;
                Lpt_Com.Comm_Addr:=889;
                Instr.Timer_Delay:=1;
                edit2.text:='O.K.';
           end
        else if edit2.text='LPT2' then
             begin
                  Lpt_Com.Comm_Port:=edit2.text;
                  Lpt_Com.Comm_Addr:=633;
                  Instr.Timer_Delay:=2;
                  edit2.text:='O.K.';
             end
        else if edit2.text='LPT3' then
             begin
                  Lpt_Com.Comm_Port:=edit2.text;
                  Lpt_Com.Comm_Addr:=377;
                  Instr.Timer_Delay:=3;
                  edit2.text:='O.K.';
             end
        else messagedlg('This is not a valid Port number',mtError,[mbok],0);
        if edit2.text='O.K.' then
           begin
                Lpt_Com.Close_Port;
                Lpt_Com.Open_Port;
                Lpt_Com.Tag:=1;
           end;
   end
else if Input_Conf then
     begin
          Input_Conf:=false;
          Instr.Input_Word:=strtoint(edit2.text);
          Input_Idle:=Instr.Input_Word;
     end
else if Output_Conf then
     begin
          Output_Conf:=false;
          Instr.Out_Word_Fall:=strtoint(edit2.text);
          Out_Protection:=Instr.Out_Word_Fall;
     end;
seek(FCode_Exe,Count);
write(FCode_Exe,Instr);
Count:=I;
seek(FCode_Exe,Count);
panel1.caption:=Info_Tag1;
edit2.text:='';
Pref1.hide;
Update_Session;
end;

procedure TMainForm.But_Set_AbortClick(Sender: TObject);
begin
panel1.caption:=Info_Tag1;
Pref1.hide;
Lpt_Conf:=false;
Input_Conf:=false;
Output_Conf:=false;
Update_Session;
end;

procedure TMainForm.Out_Status1Click(Sender: TObject);
begin
Info_Tag1:=panel1.caption;
panel1.caption:='Define Output "Imergency State" value';
Output_Conf:=true;
Pref1.show;
edit2.text:=inttostr(Out_Protection);
activecontrol:=edit2;
Update_Session;
end;

procedure TMainForm.Save1Click(Sender: TObject);
Const
     Conflict_Message = 'There is 1 or more individual bit which are set and reset simultaneously,'+
     ' or both "Input" and "Output" are enabled...!';
Var
   Bit_Conflict :Boolean;
begin
Bit_Conflict:=false;
if (H0.checked and L0.checked)then Bit_Conflict:=true;
if (H1.checked and L1.checked)then Bit_Conflict:=true;
if (H2.checked and L2.checked)then Bit_Conflict:=true;
if (H3.checked and L3.checked)then Bit_Conflict:=true;
if (H4.checked and L4.checked)then Bit_Conflict:=true;
if (H5.checked and L5.checked)then Bit_Conflict:=true;
if (H6.checked and L6.checked)then Bit_Conflict:=true;
if (H7.checked and L7.checked)then Bit_Conflict:=true;
if (checkbox1.checked and checkbox10.checked)then Bit_Conflict:=true;
if not(Bit_Conflict)then
   begin
        Store_instr;
        read(FCode_Exe,Instr);
        seek(FCode_Exe,Count);
        Update_Prog_Window;
        Update_Session;
   end
else messagedlg(Conflict_Message,mterror,[mbok],0);
end;

procedure TMainForm.Edit1Change(Sender: TObject);
begin
Modified:=true;
Update_Session;
end;

procedure TMainForm.Update_Prog_Window;
begin
if Count>0 then Panel1.caption:='Line number: '+inttostr(Count)+' out of '+inttostr(filesize(FCode_Exe)-1)
else Panel1.caption:='Programming Window';
{Flags}
if Instr.Input_En then checkbox1.checked:=true
else checkbox1.checked:=false;
if Instr.Out_En then checkbox10.checked:=true
else checkbox10.checked:=false;
if Instr.Timer_En then checkbox19.checked:=true
else checkbox19.checked:=false;
if Instr.Hold_Out then Hold.checked:=true
else Hold.checked:=false;
{Input register}
if ((Instr.Input_Word)and(1)=1)then checkbox2.checked:=true
else checkbox2.checked:=false;
if ((Instr.Input_Word)and(2)=2)then checkbox3.checked:=true
else checkbox3.checked:=false;
if ((Instr.Input_Word)and(4)=4)then checkbox4.checked:=true
else checkbox4.checked:=false;
if ((Instr.Input_Word)and(8)=8)then checkbox5.checked:=true
else checkbox5.checked:=false;
if ((Instr.Input_Word)and(16)=16)then checkbox6.checked:=true
else checkbox6.checked:=false;
if ((Instr.Input_Word)and(32)=32)then checkbox7.checked:=true
else checkbox7.checked:=false;
if ((Instr.Input_Word)and(64)=64)then checkbox8.checked:=true
else checkbox8.checked:=false;
if ((Instr.Input_Word)and(128)=128)then checkbox9.checked:=true
else checkbox9.checked:=false;
{-----------------------------------------------------}
{Output HIGH register}
if ((Instr.Out_Word_Raise)and(1)=1)then H0.checked:=true
else H0.checked:=false;
if ((Instr.Out_Word_Raise)and(2)=2)then H1.checked:=true
else H1.checked:=false;
if ((Instr.Out_Word_Raise)and(4)=4)then H2.checked:=true
else H2.checked:=false;
if ((Instr.Out_Word_Raise)and(8)=8)then H3.checked:=true
else H3.checked:=false;
if ((Instr.Out_Word_Raise)and(16)=16)then H4.checked:=true
else H4.checked:=false;
if ((Instr.Out_Word_Raise)and(32)=32)then H5.checked:=true
else H5.checked:=false;
if ((Instr.Out_Word_Raise)and(64)=64)then H6.checked:=true
else H6.checked:=false;
if ((Instr.Out_Word_Raise)and(128)=128)then H7.checked:=true
else H7.checked:=false;
{-----------------------------------------------------}
{Output LOW register}
if ((Instr.Out_Word_Fall)and(1)=0)then L0.checked:=true
else L0.checked:=false;
if ((Instr.Out_Word_Fall)and(2)=0)then L1.checked:=true
else L1.checked:=false;
if ((Instr.Out_Word_Fall)and(4)=0)then L2.checked:=true
else L2.checked:=false;
if ((Instr.Out_Word_Fall)and(8)=0)then L3.checked:=true
else L3.checked:=false;
if ((Instr.Out_Word_Fall)and(16)=0)then L4.checked:=true
else L4.checked:=false;
if ((Instr.Out_Word_Fall)and(32)=0)then L5.checked:=true
else L5.checked:=false;
if ((Instr.Out_Word_Fall)and(64)=0)then L6.checked:=true
else L6.checked:=false;
if ((Instr.Out_Word_Fall)and(128)=0)then L7.checked:=true
else L7.checked:=false;
{-----------------------------------------------------}
edit1.text:=inttostr(Instr.Timer_Delay);
Modified:=false;
end;

procedure TMainForm.Store_Instr;
begin
Clear_Record;
{Store Flags}
if CheckBox1.checked then Instr.Input_En:=true
else Instr.Input_En:=false;
if CheckBox10.checked then Instr.Out_En:=true
else Instr.Out_En:=false;
if CheckBox19.checked then Instr.Timer_En:=true
else Instr.Timer_En:=false;
if Hold.checked then Instr.Hold_Out:=true
else Instr.Hold_Out:=false;
{-----------------------------------------------------}
{Store Input register}
if checkbox2.checked then Instr.Input_Word:=(Instr.Input_Word)or(1)
else Instr.Input_Word:=(Instr.Input_Word)and(254);
if checkbox3.checked then Instr.Input_Word:=(Instr.Input_Word)or(2)
else Instr.Input_Word:=(Instr.Input_Word)and(253);
if checkbox4.checked then Instr.Input_Word:=(Instr.Input_Word)or(4)
else Instr.Input_Word:=(Instr.Input_Word)and(251);
if checkbox5.checked then Instr.Input_Word:=(Instr.Input_Word)or(8)
else Instr.Input_Word:=(Instr.Input_Word)and(247);
if checkbox6.checked then Instr.Input_Word:=(Instr.Input_Word)or(16)
else Instr.Input_Word:=(Instr.Input_Word)and(239);
if checkbox7.checked then Instr.Input_Word:=(Instr.Input_Word)or(32)
else Instr.Input_Word:=(Instr.Input_Word)and(223);
if checkbox8.checked then Instr.Input_Word:=(Instr.Input_Word)or(64)
else Instr.Input_Word:=(Instr.Input_Word)and(191);
if checkbox9.checked then Instr.Input_Word:=(Instr.Input_Word)or(128)
else Instr.Input_Word:=(Instr.Input_Word)and(127);
{-----------------------------------------------------}
{Store Output HIGH register}
if H0.checked then Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)or(1)
else Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)and(254);
if H1.checked then Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)or(2)
else Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)and(253);
if H2.checked then Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)or(4)
else Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)and(251);
if H3.checked then Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)or(8)
else Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)and(247);
if H4.checked then Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)or(16)
else Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)and(239);
if H5.checked then Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)or(32)
else Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)and(223);
if H6.checked then Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)or(64)
else Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)and(191);
if H7.checked then Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)or(128)
else Instr.Out_Word_Raise:=(Instr.Out_Word_Raise)and(127);
{-----------------------------------------------------}
{Store Output LOW register}
if L0.checked then Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)and(254)
else Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)or(1);
if L1.checked then Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)and(253)
else Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)or(2);
if L2.checked then Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)and(251)
else Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)or(4);
if L3.checked then Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)and(247)
else Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)or(8);
if L4.checked then Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)and(239)
else Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)or(16);
if L5.checked then Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)and(223)
else Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)or(32);
if L6.checked then Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)and(191)
else Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)or(64);
if L7.checked then Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)and(127)
else Instr.Out_Word_Fall:=(Instr.Out_Word_Fall)or(128);
{-----------------------------------------------------}
Instr.Timer_Delay:=strtoint(edit1.text);
seek(FCode_Exe,Count);
write(FCode_Exe,Instr);
seek(FCode_Exe,Count);
Modified:=false;
end;

procedure TMainForm.But_Next_InstrClick(Sender: TObject);
begin
Count:=Count+1;
seek(FCode_Exe,Count);
if not(eof(FCode_Exe))then
   begin
        read(FCode_Exe,Instr);
        seek(FCode_Exe,Count);
        Update_Prog_Window;
   end;
Update_Session;
end;

procedure TMainForm.But_Prev_InstrClick(Sender: TObject);
begin
Count:=Count-1;
seek(FCode_Exe,Count);
read(FCode_Exe,Instr);
seek(FCode_Exe,Count);
Update_Prog_Window;
Update_Session;
end;

procedure TMainForm.But_New_InstrClick(Sender: TObject);
begin
repeat
Count:=Count+1;
seek(FCode_Exe,Count);
until eof(FCode_Exe);
if (Count<=Line_Limit) then
   begin
        Clear_Record;
        Update_Prog_Window;
        modified:=true;
        panel1.caption:='Configure new instruction line';
   end
else
    begin
         Count:=Count-1;
         seek(FCode_Exe,Count);
         read(FCode_Exe,Instr);
         seek(FCode_Exe,Count);
         Update_Prog_Window;
         panel1.caption:='Program file is full (limited to '+inttostr(Line_Limit)+' lines)';
    end;
Update_Session;
end;

procedure TMainForm.Undo_Item1Click(Sender: TObject);
begin
Count:=filepos(FCode_Exe);
seek(FCode_Exe,Count);
if eof(FCode_Exe)then
   begin
        Count:=Count-1;
        seek(FCode_Exe,Count);
   end;
read(FCode_Exe,Instr);
if Count=0 then Clear_Record;
seek(FCode_Exe,Count);
Update_Prog_Window;
Update_Session;
end;

procedure TMainForm.Del_Item1Click(Sender: TObject);
Var
   Current_Position :Integer;
begin
Current_Position:=filepos(FCode_Exe);
Count:=filesize(FCode_Exe)-1;
seek(FCode_Exe,Count);
read(FCode_Exe,Instr);
seek(FCode_Exe,Count);
truncate(FCode_Exe);
Count:=Current_Position;
seek(FCode_Exe,Count);
if eof(FCode_Exe)then
   begin
        Count:=Count-1;
        seek(FCode_Exe,Count);
   end;
read(FCode_Exe,Instr);
if Count=0 then Clear_Record;
seek(FCode_Exe,Count);
Update_Prog_Window;
Update_Session;
end;

procedure TMainform.Exit_Upio_Environment;
begin
if File_Opened then
   begin
        if Modified then
           begin
                if messagedlg('Current Program is not saved. Save it now...?',mtwarning,[mbYes,mbNo],0)=mryes then
                   begin
                        if Count>0 then Store_Instr
                        else
                            begin
                                 Count:=0;
                                 Instr.Timer_Delay:=2;
                                 Instr.Input_Word:=255;
                                 Instr.Out_Word_Fall:=0;
                                 seek(FCode_Exe,Count);
                                 write(FCode_Exe,Instr);
                                 seek(FCode_Exe,Count);
                            end;
                   end;
           end;
        Stop_Program;
   end;
Application.Terminate;
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Exit_Upio_Environment;
end;

procedure TMainForm.Exit1Click(Sender: TObject);
begin
Exit_Upio_Environment;
end;

procedure TMainForm.HelpContents1Click(Sender: TObject);
begin
messagedlg('Sorry...! On-Line Help is not yet available.',mtinformation,[mbok],0);
end;

procedure TMainForm.EnableHints1Click(Sender: TObject);
begin
if not(Mainform.showhint)then
   begin
        Mainform.showhint:=true;
        EnableHints1.checked:=true;
   end
else
    begin
         Mainform.showhint:=false;
         EnableHints1.checked:=false;
    end;
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
begin
Timer1.enabled:=false;
Output_Flow:=true;
end;

end.
