mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 22:11:12 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			695 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			695 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| {
 | |
|     This file is part of the Free Pascal run time library.
 | |
|     Copyright (c) 1999-2000 by the Free Pascal development team.
 | |
| 
 | |
|     See the file COPYING.FPC, included in this distribution,
 | |
|     for details about the copyright.
 | |
| 
 | |
|     This program is distributed in the hope that it will be useful,
 | |
|     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | |
| 
 | |
|  **********************************************************************}
 | |
| unit System;
 | |
| 
 | |
| interface
 | |
| 
 | |
| { two debug conditionnals can be used
 | |
|   - SYSTEMDEBUG
 | |
|     -for STACK checks
 | |
|     -for non closed files at exit (or at any time with GDB)
 | |
|   - SYSTEM_DEBUG_STARTUP
 | |
|     specifically for
 | |
|     - proxy command line (DJGPP feature)
 | |
|     - list of args
 | |
|     - list of env variables  (PM) }
 | |
| 
 | |
| {$define FPC_IS_SYSTEM}
 | |
| {$ifndef NO_EXCEPTIONS_IN_SYSTEM}
 | |
| {$define EXCEPTIONS_IN_SYSTEM}
 | |
| {$endif NO_EXCEPTIONS_IN_SYSTEM}
 | |
| {$define USE_NOTHREADMANAGER}
 | |
| 
 | |
| { include system-independent routine headers }
 | |
| 
 | |
| {$I systemh.inc}
 | |
| {$I portsh.inc}
 | |
| 
 | |
| 
 | |
| const
 | |
|  LineEnding = #13#10;
 | |
| { LFNSupport is a variable here, defined below!!! }
 | |
|  DirectorySeparator = '\';
 | |
|  DriveSeparator = ':';
 | |
|  ExtensionSeparator = '.';
 | |
|  PathSeparator = ';';
 | |
|  AllowDirectorySeparators : set of AnsiChar = ['\','/'];
 | |
|  AllowDriveSeparators : set of AnsiChar = [':'];
 | |
| { FileNameCaseSensitive and FileNameCasePreserving are defined separately below!!! }
 | |
|  maxExitCode = 255;
 | |
|  MaxPathLen = 256;
 | |
| 
 | |
| const
 | |
| { Default filehandles }
 | |
|   UnusedHandle    = -1;
 | |
|   StdInputHandle  = 0;
 | |
|   StdOutputHandle = 1;
 | |
|   StdErrorHandle  = 2;
 | |
| 
 | |
|   FileNameCaseSensitive : boolean = false;
 | |
|   FileNameCasePreserving: boolean = false;
 | |
|   CtrlZMarksEOF: boolean = true; (* #26 is considered as end of file *)
 | |
| 
 | |
|   sLineBreak = LineEnding;
 | |
|   DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
 | |
| 
 | |
| { Default memory segments (Tp7 compatibility) }
 | |
|   seg0040 = $0040;
 | |
|   segA000 = $A000;
 | |
|   segB000 = $B000;
 | |
|   segB800 = $B800;
 | |
| 
 | |
| var
 | |
| { Mem[] support }
 | |
|   mem  : array[0..$7fffffff-1] of byte absolute $0:$0;
 | |
|   memw : array[0..($7fffffff div sizeof(word))-1] of word absolute $0:$0;
 | |
|   meml : array[0..($7fffffff div sizeof(longint))-1] of longint absolute $0:$0;
 | |
| { C-compatible arguments and environment }
 | |
|   argc:longint;public name 'operatingsystem_parameter_argc';
 | |
|   argv:PPAnsiChar;public name 'operatingsystem_parameter_argv';
 | |
|   envp:PPAnsiChar;public name 'operatingsystem_parameter_envp';
 | |
|   dos_argv0 : PAnsiChar; public name 'dos_argv0';
 | |
| 
 | |
|   AllFilesMask: string [3];
 | |
| 
 | |
| {$ifndef RTLLITE}
 | |
| { System info }
 | |
|   LFNSupport : boolean;
 | |
| {$ELSE RTLLITE}
 | |
| const
 | |
|   LFNSupport = false;
 | |
| {$endif RTLLITE}
 | |
| 
 | |
| type
 | |
| { Dos Extender info }
 | |
|   p_stub_info = ^t_stub_info;
 | |
|   t_stub_info = packed record
 | |
|        magic         : array[0..15] of AnsiChar;
 | |
|        size          : longint;
 | |
|        minstack      : longint;
 | |
|        memory_handle : longint;
 | |
|        initial_size  : longint;
 | |
|        minkeep       : word;
 | |
|        ds_selector   : word;
 | |
|        ds_segment    : word;
 | |
|        psp_selector  : word;
 | |
|        cs_selector   : word;
 | |
|        env_size      : word;
 | |
|        basename      : array[0..7] of AnsiChar;
 | |
|        argv0         : array [0..15] of AnsiChar;
 | |
|        dpmi_server   : array [0..15] of AnsiChar;
 | |
|   end;
 | |
| 
 | |
|   p_go32_info_block = ^t_go32_info_block;
 | |
|   t_go32_info_block = packed record
 | |
|        size_of_this_structure_in_bytes    : longint; {offset 0}
 | |
|        linear_address_of_primary_screen   : longint; {offset 4}
 | |
|        linear_address_of_secondary_screen : longint; {offset 8}
 | |
|        linear_address_of_transfer_buffer  : longint; {offset 12}
 | |
|        size_of_transfer_buffer            : longint; {offset 16}
 | |
|        pid                                : longint; {offset 20}
 | |
|        master_interrupt_controller_base   : byte; {offset 24}
 | |
|        slave_interrupt_controller_base    : byte; {offset 25}
 | |
|        selector_for_linear_memory         : word; {offset 26}
 | |
|        linear_address_of_stub_info_structure : longint; {offset 28}
 | |
|        linear_address_of_original_psp     : longint; {offset 32}
 | |
|        run_mode                           : word; {offset 36}
 | |
|        run_mode_info                      : word; {offset 38}
 | |
|   end;
 | |
| 
 | |
| var
 | |
|   stub_info       : p_stub_info; public name 'operatingsystem_stub_info';
 | |
|   go32_info_block : t_go32_info_block; public name 'operatingsystem_go32_info_block';
 | |
| {$ifdef SYSTEMDEBUG}
 | |
| const
 | |
|    accept_sbrk : boolean = true;
 | |
| {$endif}
 | |
| 
 | |
| {
 | |
|   necessary for objects.pas, should be removed (at least from the interface
 | |
|   to the implementation)
 | |
| }
 | |
|   type
 | |
|     trealregs=record
 | |
|       realedi,realesi,realebp,realres,
 | |
|       realebx,realedx,realecx,realeax : longint;
 | |
|       realflags,
 | |
|       reales,realds,realfs,realgs,
 | |
|       realip,realcs,realsp,realss  : word;
 | |
|     end;
 | |
|   function  do_write(h:longint;addr:pointer;len : longint) : longint;
 | |
|   function  do_read(h:longint;addr:pointer;len : longint) : longint;
 | |
|   procedure syscopyfromdos(addr : longint; len : longint);
 | |
|   procedure syscopytodos(addr : longint; len : longint);
 | |
|   procedure sysrealintr(intnr : word;var regs : trealregs);
 | |
|   function  tb : longint;
 | |
| 
 | |
| implementation
 | |
| 
 | |
| { include system independent routines }
 | |
| 
 | |
| {$I system.inc}
 | |
| {$I ports.inc}
 | |
| 
 | |
| 
 | |
| var
 | |
|   c_environ : PPAnsiChar;external name '__environ';
 | |
|   _args : PPAnsiChar;external name '_args';
 | |
|   __stubinfo : p_stub_info;external name '__stubinfo';
 | |
|   ___dos_argv0 : PAnsiChar;external name '___dos_argv0';
 | |
| 
 | |
| 
 | |
| procedure setup_arguments;
 | |
| type
 | |
|   arrayword = array [0..255] of word;
 | |
| var
 | |
|   psp      : word;
 | |
|   proxy_s  : string[50];
 | |
|   proxy_argc,proxy_seg,proxy_ofs,lin : longint;
 | |
|   rm_argv  : ^arrayword;
 | |
|   argv0len : longint;
 | |
|   useproxy : boolean;
 | |
|   hp       : PPAnsiChar;
 | |
|   doscmd   : string[129];  { Dos commandline copied from PSP, max is 128 chars +1 for terminating zero }
 | |
|   arglen,cmdlen,
 | |
|   count   : longint;
 | |
|   argstart,
 | |
|   pc,arg  : PAnsiChar;
 | |
|   quote   : AnsiChar;
 | |
|   argvlen : longint;
 | |
| 
 | |
|   function atohex(s : PAnsiChar) : longint;
 | |
|   var
 | |
|     rv : longint;
 | |
|     v  : byte;
 | |
|   begin
 | |
|     rv:=0;
 | |
|     while (s^<>#0) do
 | |
|      begin
 | |
|        v:=byte(s^)-byte('0');
 | |
|        if (v > 9) then
 | |
|          dec(v,7);
 | |
|        v:=v and 15; { in case it's lower case }
 | |
|        rv:=(rv shl 4) or v;
 | |
|        inc(longint(s));
 | |
|      end;
 | |
|     atohex:=rv;
 | |
|   end;
 | |
| 
 | |
|   procedure allocarg(idx,len:longint);
 | |
|     var
 | |
|       oldargvlen : longint;
 | |
|     begin
 | |
|       if idx>=argvlen then
 | |
|        begin
 | |
|          oldargvlen:=argvlen;
 | |
|          argvlen:=(idx+8) and (not 7);
 | |
|          sysreallocmem(argv,argvlen*sizeof(pointer));
 | |
|          fillchar(argv[oldargvlen],(argvlen-oldargvlen)*sizeof(pointer),0);
 | |
|        end;
 | |
|       { use realloc to reuse already existing memory }
 | |
|       { always allocate, even if length is zero, since }
 | |
|       { the arg. is still present!                     }
 | |
|       sysreallocmem(argv[idx],len+1);
 | |
|     end;
 | |
| 
 | |
| begin
 | |
|   count:=0;
 | |
|   argc:=1;
 | |
|   argv:=nil;
 | |
|   argvlen:=0;
 | |
|   { load commandline from psp }
 | |
|   psp:=stub_info^.psp_selector;
 | |
|   sysseg_move(psp, 128, get_ds, longint(@doscmd), 128);
 | |
|   doscmd[length(doscmd)+1]:=#0;
 | |
| {$IfDef SYSTEM_DEBUG_STARTUP}
 | |
|   Writeln(stderr,'Dos command line is #',doscmd,'# size = ',length(doscmd));
 | |
| {$EndIf }
 | |
|   { create argv[0] }
 | |
|   argv0len:=strlen(dos_argv0);
 | |
|   allocarg(count,argv0len+1);
 | |
|   move(dos_argv0^,argv[count]^,argv0len+1);
 | |
|   inc(count);
 | |
|   { setup cmdline variable }
 | |
|   cmdlen:=argv0len+length(doscmd)+2;
 | |
|   cmdline:=Getmem(cmdlen);
 | |
|   move(dos_argv0^,cmdline^,argv0len);
 | |
|   cmdline[argv0len]:=' ';
 | |
|   inc(argv0len);
 | |
|   move(doscmd[1],cmdline[argv0len],length(doscmd));
 | |
|   cmdline[cmdlen-1]:=#0;
 | |
|   { parse dos commandline }
 | |
|   pc:=@doscmd[1];
 | |
|   while pc^<>#0 do
 | |
|    begin
 | |
|      { skip leading spaces }
 | |
|      while pc^ in [#1..#32] do
 | |
|       inc(pc);
 | |
|      if pc^=#0 then
 | |
|       break;
 | |
|      { calc argument length }
 | |
|      quote:=' ';
 | |
|      argstart:=pc;
 | |
|      arglen:=0;
 | |
|      while (pc^<>#0) do
 | |
|       begin
 | |
|         case pc^ of
 | |
|           #1..#32 :
 | |
|             begin
 | |
|               if quote<>' ' then
 | |
|                inc(arglen)
 | |
|               else
 | |
|                break;
 | |
|             end;
 | |
|           '"' :
 | |
|             begin
 | |
|               if quote<>'''' then
 | |
|                begin
 | |
|                  if PAnsiChar(pc+1)^<>'"' then
 | |
|                   begin
 | |
|                     if quote='"' then
 | |
|                      quote:=' '
 | |
|                     else
 | |
|                      quote:='"';
 | |
|                   end
 | |
|                  else
 | |
|                   inc(pc);
 | |
|                end
 | |
|               else
 | |
|                inc(arglen);
 | |
|             end;
 | |
|           '''' :
 | |
|             begin
 | |
|               if quote<>'"' then
 | |
|                begin
 | |
|                  if PAnsiChar(pc+1)^<>'''' then
 | |
|                   begin
 | |
|                     if quote=''''  then
 | |
|                      quote:=' '
 | |
|                     else
 | |
|                      quote:='''';
 | |
|                   end
 | |
|                  else
 | |
|                   inc(pc);
 | |
|                end
 | |
|               else
 | |
|                inc(arglen);
 | |
|             end;
 | |
|           else
 | |
|             inc(arglen);
 | |
|         end;
 | |
|         inc(pc);
 | |
|       end;
 | |
|      { copy argument }
 | |
|      allocarg(count,arglen);
 | |
|      quote:=' ';
 | |
|      pc:=argstart;
 | |
|      arg:=argv[count];
 | |
|      while (pc^<>#0) do
 | |
|       begin
 | |
|         case pc^ of
 | |
|           #1..#32 :
 | |
|             begin
 | |
|               if quote<>' ' then
 | |
|                begin
 | |
|                  arg^:=pc^;
 | |
|                  inc(arg);
 | |
|                end
 | |
|               else
 | |
|                break;
 | |
|             end;
 | |
|           '"' :
 | |
|             begin
 | |
|               if quote<>'''' then
 | |
|                begin
 | |
|                  if PAnsiChar(pc+1)^<>'"' then
 | |
|                   begin
 | |
|                     if quote='"' then
 | |
|                      quote:=' '
 | |
|                     else
 | |
|                      quote:='"';
 | |
|                   end
 | |
|                  else
 | |
|                   inc(pc);
 | |
|                end
 | |
|               else
 | |
|                begin
 | |
|                  arg^:=pc^;
 | |
|                  inc(arg);
 | |
|                end;
 | |
|             end;
 | |
|           '''' :
 | |
|             begin
 | |
|               if quote<>'"' then
 | |
|                begin
 | |
|                  if PAnsiChar(pc+1)^<>'''' then
 | |
|                   begin
 | |
|                     if quote=''''  then
 | |
|                      quote:=' '
 | |
|                     else
 | |
|                      quote:='''';
 | |
|                   end
 | |
|                  else
 | |
|                   inc(pc);
 | |
|                end
 | |
|               else
 | |
|                begin
 | |
|                  arg^:=pc^;
 | |
|                  inc(arg);
 | |
|                end;
 | |
|             end;
 | |
|           else
 | |
|             begin
 | |
|               arg^:=pc^;
 | |
|               inc(arg);
 | |
|             end;
 | |
|         end;
 | |
|         inc(pc);
 | |
|       end;
 | |
|      arg^:=#0;
 | |
|  {$IfDef SYSTEM_DEBUG_STARTUP}
 | |
|      Writeln(stderr,'dos arg ',count,' #',arglen,'#',argv[count],'#');
 | |
|  {$EndIf SYSTEM_DEBUG_STARTUP}
 | |
|      inc(count);
 | |
|    end;
 | |
|   argc:=count;
 | |
|   { check for !proxy for long commandlines passed using environment }
 | |
|   hp:=envp;
 | |
|   useproxy:=false;
 | |
|   while assigned(hp^) do
 | |
|    begin
 | |
|      if (hp^[0]=' ') then
 | |
|       begin
 | |
|         proxy_s:=strpas(hp^);
 | |
|         if Copy(proxy_s,1,7)=' !proxy' then
 | |
|          begin
 | |
|            proxy_s[13]:=#0;
 | |
|            proxy_s[18]:=#0;
 | |
|            proxy_s[23]:=#0;
 | |
|            { Do not set argv[2..4] to PROXY_S
 | |
|              values, because PROXY_S is on stack,
 | |
|              while ARGV[2..4] need to be on heap.
 | |
|              PM 2011-06-08
 | |
|            argv[2]:=@proxy_s[9];
 | |
|            argv[3]:=@proxy_s[14];
 | |
|            argv[4]:=@proxy_s[19];}
 | |
|            allocarg(2,4);
 | |
|            strcopy(argv[2], @proxy_s[9]);
 | |
|            allocarg(3,4);
 | |
|            strcopy(argv[3], @proxy_s[14]);
 | |
|            allocarg(4,4);
 | |
|            strcopy(argv[4], @proxy_s[19]);
 | |
|            { We need to change this variable env name
 | |
|              otherwise it will be used by other DJGPP variables
 | |
|              if we call them. PM 2011-07-04
 | |
|              Hide it as '_!proxy' instead of ' !proxy' }
 | |
|            hp^[0]:='_';
 | |
|            useproxy:=true;
 | |
|            break;
 | |
|          end;
 | |
|       end;
 | |
|      inc(hp);
 | |
|    end;
 | |
|   { check for !proxy for long commandlines passed using commandline }
 | |
|   if (not useproxy) and
 | |
|      (argc > 1) and (far_strlen(get_ds,longint(argv[1])) = 6)  then
 | |
|    begin
 | |
|      move(argv[1]^,proxy_s[1],6);
 | |
|      proxy_s[0] := #6;
 | |
|      if (proxy_s = '!proxy') then
 | |
|       useproxy:=true;
 | |
|    end;
 | |
|   { use proxy when found }
 | |
|   if useproxy then
 | |
|    begin
 | |
|      proxy_argc:=atohex(argv[2]);
 | |
|      proxy_seg:=atohex(argv[3]);
 | |
|      proxy_ofs:=atohex(argv[4]);
 | |
| {$IfDef SYSTEM_DEBUG_STARTUP}
 | |
|      Writeln(stderr,'proxy command line found');
 | |
|      writeln(stderr,'argc: ',proxy_argc,' seg: ',proxy_seg,' ofs: ',proxy_ofs);
 | |
| {$EndIf SYSTEM_DEBUG_STARTUP}
 | |
|      rm_argv:=SysGetmem(proxy_argc*sizeof(word));
 | |
|      sysseg_move(dos_selector,proxy_seg*16+proxy_ofs, get_ds,longint(rm_argv),proxy_argc*sizeof(word));
 | |
|      for count:=0 to proxy_argc - 1 do
 | |
|       begin
 | |
|         lin:=proxy_seg*16+rm_argv^[count];
 | |
|         arglen:=far_strlen(dos_selector,lin);
 | |
|         allocarg(count,arglen);
 | |
|         sysseg_move(dos_selector,lin,get_ds,longint(argv[count]),arglen+1);
 | |
| {$IfDef SYSTEM_DEBUG_STARTUP}
 | |
|         Writeln(stderr,'arg ',count,' #',rm_argv^[count],'#',arglen,'#',argv[count],'#');
 | |
| {$EndIf SYSTEM_DEBUG_STARTUP}
 | |
|     end;
 | |
|      SysFreemem(rm_argv);
 | |
|      argc:=proxy_argc;
 | |
|    end;
 | |
|   { create an nil entry }
 | |
|   allocarg(argc,0);
 | |
|   { free unused memory }
 | |
|   sysreallocmem(argv,(argc+1)*sizeof(pointer));
 | |
|   _args:=argv;
 | |
| end;
 | |
| 
 | |
| 
 | |
| procedure setup_environment;
 | |
| var env_selector : word;
 | |
|     env_count : longint;
 | |
|     dos_env,cp : PAnsiChar;
 | |
| begin
 | |
|    stub_info:=__stubinfo;
 | |
|    dos_env := sysgetmem(stub_info^.env_size);
 | |
|    env_count:=0;
 | |
|    sysseg_move(stub_info^.psp_selector,$2c, get_ds, longint(@env_selector), 2);
 | |
|    sysseg_move(env_selector, 0, get_ds, longint(dos_env), stub_info^.env_size);
 | |
|   cp:=dos_env;
 | |
|   while cp ^ <> #0 do
 | |
|     begin
 | |
|     inc(env_count);
 | |
|     while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
 | |
|     inc(longint(cp)); { skip to next character }
 | |
|     end;
 | |
|   envp := sysgetmem((env_count+1) * sizeof(PAnsiChar));
 | |
|   if (envp = nil) then HandleError (203);
 | |
|   c_environ:=envp;
 | |
|   cp:=dos_env;
 | |
|   env_count:=0;
 | |
|   while cp^ <> #0 do
 | |
|    begin
 | |
|      envp[env_count] := sysgetmem(strlen(cp)+1);
 | |
|      strcopy(envp[env_count], cp);
 | |
| {$IfDef SYSTEM_DEBUG_STARTUP}
 | |
|      Writeln(stderr,'env ',env_count,' = "',envp[env_count],'"');
 | |
| {$EndIf SYSTEM_DEBUG_STARTUP}
 | |
|      inc(env_count);
 | |
|      while (cp^ <> #0) do
 | |
|       inc(longint(cp)); { skip to NUL }
 | |
|      inc(longint(cp)); { skip to next character }
 | |
|    end;
 | |
|   envp[env_count]:=nil;
 | |
|   longint(cp):=longint(cp)+3;
 | |
|   dos_argv0 := sysgetmem(strlen(cp)+1);
 | |
|   if (dos_argv0 = nil) then HandleError (203);
 | |
|   strcopy(dos_argv0, cp);
 | |
|   { update ___dos_argv0 also }
 | |
|   ___dos_argv0:=dos_argv0
 | |
| end;
 | |
| 
 | |
| 
 | |
| 
 | |
| {*****************************************************************************
 | |
|                          System Dependent Exit code
 | |
| *****************************************************************************}
 | |
| 
 | |
| procedure __exit(exitcode:longint);cdecl;external;
 | |
| 
 | |
| Procedure system_exit;
 | |
| var
 | |
|   h : byte;
 | |
| begin
 | |
|   for h:=0 to max_files-1 do
 | |
|     if openfiles[h] then
 | |
|       begin
 | |
| {$ifdef SYSTEMDEBUG}
 | |
|          writeln(stderr,'file ',opennames[h],' not closed at exit');
 | |
| {$endif SYSTEMDEBUG}
 | |
|          if h>=5 then
 | |
|            do_close(h);
 | |
|       end;
 | |
|   { halt is not allways called !! }
 | |
|   { not on normal exit !! PM }
 | |
|   set_pm_interrupt($00,old_int00);
 | |
| {$ifndef EXCEPTIONS_IN_SYSTEM}
 | |
|   set_pm_interrupt($75,old_int75);
 | |
| {$endif EXCEPTIONS_IN_SYSTEM}
 | |
|   __exit(exitcode);
 | |
| end;
 | |
| 
 | |
| 
 | |
| procedure new_int00;
 | |
| begin
 | |
|   HandleError(200);
 | |
| end;
 | |
| 
 | |
| 
 | |
| {$ifndef EXCEPTIONS_IN_SYSTEM}
 | |
| procedure new_int75;
 | |
| begin
 | |
|   asm
 | |
|         xorl    %eax,%eax
 | |
|         outb    %al,$0x0f0
 | |
|         movb    $0x20,%al
 | |
|         outb    %al,$0x0a0
 | |
|         outb    %al,$0x020
 | |
|   end;
 | |
|   HandleError(200);
 | |
| end;
 | |
| {$endif EXCEPTIONS_IN_SYSTEM}
 | |
| 
 | |
| 
 | |
| var
 | |
|   __stkbottom : pointer;external name '__stkbottom';
 | |
| 
 | |
| 
 | |
| 
 | |
| {*****************************************************************************
 | |
|                               ParamStr/Randomize
 | |
| *****************************************************************************}
 | |
| 
 | |
| function paramcount : longint;
 | |
| begin
 | |
|   paramcount := argc - 1;
 | |
| end;
 | |
| 
 | |
| 
 | |
| function paramstr(l : longint) : shortstring;
 | |
| begin
 | |
|   if (l>=0) and (l+1<=argc) then
 | |
|    paramstr:=strpas(argv[l])
 | |
|   else
 | |
|    paramstr:='';
 | |
| end;
 | |
| 
 | |
| 
 | |
| procedure randomize;
 | |
| var
 | |
|   hl   : longint;
 | |
|   regs : trealregs;
 | |
| begin
 | |
|   regs.realeax:=$2c00;
 | |
|   sysrealintr($21,regs);
 | |
|   hl:=lo(regs.realedx);
 | |
|   randseed:=hl*$10000+ lo(regs.realecx);
 | |
| end;
 | |
| 
 | |
| 
 | |
| {*****************************************************************************
 | |
|                          SystemUnit Initialization
 | |
| *****************************************************************************}
 | |
| 
 | |
| function CheckLFN:boolean;
 | |
| var
 | |
|   regs     : TRealRegs;
 | |
|   RootName : PAnsiChar;
 | |
| begin
 | |
| { Check LFN API on drive c:\ }
 | |
|   RootName:='C:\';
 | |
|   syscopytodos(longint(RootName),strlen(RootName)+1);
 | |
| { Call 'Get Volume Information' ($71A0) }
 | |
|   regs.realeax:=$71a0;
 | |
|   regs.reales:=tb_segment;
 | |
|   regs.realedi:=tb_offset;
 | |
|   regs.realecx:=32;
 | |
|   regs.realds:=tb_segment;
 | |
|   regs.realedx:=tb_offset;
 | |
|   regs.realflags:=carryflag;
 | |
|   sysrealintr($21,regs);
 | |
| { If carryflag=0 and LFN API bit in ebx is set then use Long file names }
 | |
|   CheckLFN:=(regs.realflags and carryflag=0) and (regs.realebx and $4000=$4000);
 | |
| end;
 | |
| 
 | |
| {$ifdef  EXCEPTIONS_IN_SYSTEM}
 | |
| {$define IN_SYSTEM}
 | |
| {$i dpmiexcp.pp}
 | |
| {$endif  EXCEPTIONS_IN_SYSTEM}
 | |
| 
 | |
| procedure SysInitStdIO;
 | |
| begin
 | |
|   OpenStdIO(Input,fmInput,StdInputHandle);
 | |
|   OpenStdIO(Output,fmOutput,StdOutputHandle);
 | |
|   OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
 | |
|   OpenStdIO(StdOut,fmOutput,StdOutputHandle);
 | |
|   OpenStdIO(StdErr,fmOutput,StdErrorHandle);
 | |
| end;
 | |
| 
 | |
| function GetProcessID: SizeUInt;
 | |
| begin
 | |
|  GetProcessID := SizeUInt (Go32_info_block.pid);
 | |
| end;
 | |
| 
 | |
| function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
 | |
| begin
 | |
|   result := stklen;
 | |
| end;
 | |
| 
 | |
| var
 | |
|   temp_int : tseginfo;
 | |
| Begin
 | |
| { v2prt0.as adds 256 bytes to __stkbottom for extra safety during stack
 | |
|   checking, so we subtract 256 here in order to calculate StackTop correctly
 | |
|   and to ensure that StackLength = StackTop - StackBottom }
 | |
|   StackLength := CheckInitialStkLen(InitialStkLen)-256;
 | |
|   StackBottom := __stkbottom;
 | |
|   { To be set if this is a GUI or console application }
 | |
|   IsConsole := TRUE;
 | |
|   { To be set if this is a library and not a program  }
 | |
|   IsLibrary := FALSE;
 | |
| { save old int 0 and 75 }
 | |
|   get_pm_interrupt($00,old_int00);
 | |
|   get_pm_interrupt($75,old_int75);
 | |
|   temp_int.segment:=get_cs;
 | |
|   temp_int.offset:=@new_int00;
 | |
|   set_pm_interrupt($00,temp_int);
 | |
| {$ifndef EXCEPTIONS_IN_SYSTEM}
 | |
|   temp_int.offset:=@new_int75;
 | |
|   set_pm_interrupt($75,temp_int);
 | |
| {$endif EXCEPTIONS_IN_SYSTEM}
 | |
| { Setup heap }
 | |
|   InitHeap;
 | |
|   SysInitExceptions;
 | |
|   initunicodestringmanager;
 | |
| { Setup stdin, stdout and stderr }
 | |
|   SysInitStdIO;
 | |
| { Setup environment and arguments }
 | |
|   Setup_Environment;
 | |
|   Setup_Arguments;
 | |
| { Use LFNSupport LFN }
 | |
|   LFNSupport:=CheckLFN;
 | |
|   if LFNSupport then
 | |
|    begin
 | |
|     FileNameCasePreserving:=true;
 | |
|     AllFilesMask := '*';
 | |
|    end
 | |
|   else
 | |
|    AllFilesMask := '*.*';
 | |
| { Reset IO Error }
 | |
|   InOutRes:=0;
 | |
| {$ifdef FPC_HAS_FEATURE_THREADING}
 | |
|   InitSystemThreads;
 | |
| {$endif}
 | |
| {$ifdef  EXCEPTIONS_IN_SYSTEM}
 | |
|   InitDPMIExcp;
 | |
|   InstallDefaultHandlers;
 | |
| {$endif  EXCEPTIONS_IN_SYSTEM}
 | |
| End.
 | 
