[B
  'PackInst' import  
 
  /LogMemo Create:LogMemo def
  /Log [B LogMemo.Log ] def
  10 LogMemo.SetFontSize
  LogMemo.Show

  % Define constants
  /BootModeRequest '@00' def
  /BootModeResponse '@C5' def
  /FlashErase '@00' def
  /BaudRate 38400 def
  /ComPort 'COM1' def
  /BufferSize 100 def  
  /TimeOut 10000 def
  /EraseTimeOut 60000 def
  /PreloaderName 'Pre_Load.dat' def
  /LoaderName 'Loader.dat' def
  /MonitorFileName 'BootOS3.H86' def
  
  /LoadBinFile [P 
    [A /FileName ]
      FileName fileexist [B
        /LogFile Create:LogFile def
        % Open the file with the mode = 0 (read only)
        FileName 0 LogFile.Open
        % Create the data container        
        /Data 0 carr def  
        [B
          LogFile.Eof [B ExitLoop ] if	
          % Read 100 characters from LogFile (or less if end of file occurs).   
          Data 100 LogFile.ReadChars add                    
        ] loop  
        LogFile.Close                         
      ]
      [B
        FileName ' does not exist.' add raisese	        
      ]	 ifelse             
    [A /Data ]
  ] def

  /LoadTextFile [P 
    [A /FileName ]
      FileName fileexist [B
        /LogFile Create:LogFile def
        % Open the file with the mode = 0 (read only)
        FileName 0 LogFile.Open
        % Create the data container        
        /Data 0 carr def  
        [B
          LogFile.Eof [B ExitLoop ] if	
          % Read line   
          Data LogFile.ReadLine add         
        ] loop  
        LogFile.Close                         
      ]             
      [B
        FileName ' does not exist.' add raisese	        
      ]	 ifelse             
    [A /Data ]
  ] def         

  % Chose the serial port for the communication with the servo controller
  PackInst:_SelectCommPort [B     
    [B      		
      /PortType exch def
      /ComPort exch def    
      % Configure and open the serial port
      /Comm Create:Comm def
      ComPort BaudRate Comm.Open
      % Create a buffer for receive the data
      /RxBuf BufferSize Comm.CreateBuffer def
      RxBuf Comm.ClearBuffer
      100 wait
      'Sending null character...' log      
      BootModeRequest Comm.SendString
      'Waiting response to null character...' log
      RxBuf TimeOut BootModeResponse Comm.WaitForChar         
      Comm.GetExpired 
      [B
        RxBuf Comm.GetBuffer log	 
        'Error: processor is not in bootstrap mode. Installation aborted.' log 
        Comm.Close
      ]  
      [B 
        PreloaderName LoadBinFile
        /Data exch def
        'Sending preloader...' log
        Data [B Comm.SendString ] forall	
        100 wait 
        LoaderName LoadBinFile 
        /Data exch def
        'Sending loader...' log
        Data [B Comm.SendString ] forall	
        RxBuf Comm.ClearBuffer
        'Waiting response from loader...' log      
        RxBuf EraseTimeOut FlashErase Comm.WaitForChar 
        Comm.GetExpired [B       	
      	  'Wrong response from loader (flash problem?). Installation aborted.' log 
        ] 
        [B      	 
          Comm.Close
			    /Device Create:Device def
			    /DeviceName 'LinMotInstall' def      	
			    'PortName' ComPort 1 DeviceName 'LinMotInstall' Device.CreateDevice
			    DeviceName /PackInst:OnMessageCallback PackInst:Init
			    [B
			      % load monitor file
			      /Data MonitorFileName LoadTextFile def        	
			      'Sending monitor software...' log 
			      Data MonitorFileName PackInst:DownloadH86File        
			      PackInst:ResetDevice            
			      'Monitor software loaded successfully.' log



			      PIVar:LogMemo.Hide
			    ] if
			    Device.DestroyDevice
        ] ifelse     
      ] ifelse                                        
    ] 
    [B
      /Dict exch def
      Dict.Msg ' Installation aborted!' add log
    ] tryexcept	  
  ] if           
      
  LogMemo.Remain  
]