mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-10 11:32:46 +02:00

instead of copying it to a local var first, since the concern about PIC code (this asm code started out as a copy of the i386 rtl code) doesn't exist on the i8086, since there's no such thing as PIC code on the i8086 git-svn-id: trunk@41311 -
719 lines
18 KiB
ObjectPascal
719 lines
18 KiB
ObjectPascal
unit System;
|
|
|
|
|
|
interface
|
|
|
|
{ The heap for MSDOS is implemented
|
|
in tinyheap.inc include file,
|
|
but it uses default SysGetMem names }
|
|
|
|
{$define HAS_MEMORYMANAGER}
|
|
{ define TEST_FPU_INT10 to force keeping local int10,
|
|
for testing purpose only }
|
|
|
|
|
|
{$DEFINE FPC_INCLUDE_SOFTWARE_MUL}
|
|
{$DEFINE FPC_INCLUDE_SOFTWARE_MOD_DIV}
|
|
|
|
{$DEFINE FPC_USE_SMALL_DEFAULTSTACKSIZE}
|
|
{ To avoid warnings in thread.inc code,
|
|
but value must be really given after
|
|
systemh.inc is included otherwise the
|
|
$mode switch is not effective }
|
|
|
|
{ Use Ansi Char for files }
|
|
{$define FPC_ANSI_TEXTFILEREC}
|
|
{$define FPC_STDOUT_TRUE_ALIAS}
|
|
|
|
{$ifdef NO_WIDESTRINGS}
|
|
{ Do NOT use wide Char for files }
|
|
{$undef FPC_HAS_FEATURE_WIDESTRINGS}
|
|
{$endif NO_WIDESTRINGS}
|
|
|
|
{$I systemh.inc}
|
|
{$I tnyheaph.inc}
|
|
{$I portsh.inc}
|
|
|
|
const
|
|
LineEnding = #13#10;
|
|
{ LFNSupport is a variable here, defined below!!! }
|
|
DirectorySeparator = '\';
|
|
DriveSeparator = ':';
|
|
ExtensionSeparator = '.';
|
|
PathSeparator = ';';
|
|
AllowDirectorySeparators : set of char = ['\','/'];
|
|
AllowDriveSeparators : set of char = [':'];
|
|
{ FileNameCaseSensitive and FileNameCasePreserving are defined separately below!!! }
|
|
maxExitCode = 255;
|
|
MaxPathLen = 256;
|
|
|
|
const
|
|
{ Default filehandles }
|
|
UnusedHandle = $ffff;{ instead of -1, as it is a word value}
|
|
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: Word = $0040;
|
|
segA000: Word = $A000;
|
|
segB000: Word = $B000;
|
|
segB800: Word = $B800;
|
|
{ The value that needs to be added to the segment to move the pointer by
|
|
64K bytes (BP7 compatibility) }
|
|
SelectorInc: Word = $1000;
|
|
|
|
var
|
|
{ Mem[] support }
|
|
mem : array[0..$7fff-1] of byte absolute $0:$0;
|
|
memw : array[0..($7fff div sizeof(word))-1] of word absolute $0:$0;
|
|
meml : array[0..($7fff div sizeof(longint))-1] of longint absolute $0:$0;
|
|
{ C-compatible arguments and environment }
|
|
argc:smallint; //!! public name 'operatingsystem_parameter_argc';
|
|
argv:PPchar; //!! public name 'operatingsystem_parameter_argv';
|
|
|
|
{ The DOS Program Segment Prefix segment (TP7 compatibility) }
|
|
PrefixSeg:Word;public name '__fpc_PrefixSeg';
|
|
|
|
SaveInt00: FarPointer;public name '__SaveInt00';
|
|
SaveInt10: FarPointer;public name '__SaveInt10';
|
|
SaveInt75: FarPointer;public name '__SaveInt75';
|
|
fpu_status: word;public name '__fpu_status';
|
|
|
|
|
|
AllFilesMask: string [3];
|
|
{$ifndef RTLLITE}
|
|
{ System info }
|
|
LFNSupport : boolean;
|
|
{$ELSE RTLLITE}
|
|
const
|
|
LFNSupport = false;
|
|
{$endif RTLLITE}
|
|
|
|
implementation
|
|
|
|
procedure DebugWrite(const S: string); forward;
|
|
procedure DebugWriteLn(const S: string); forward;
|
|
|
|
const
|
|
fCarry = 1;
|
|
|
|
{ used for an offset fixup for accessing the proc parameters in asm routines
|
|
that use nostackframe. We can't use the parameter name directly, because
|
|
i8086 doesn't support sp relative addressing. }
|
|
{$ifdef FPC_X86_CODE_FAR}
|
|
extra_param_offset = 2;
|
|
{$else FPC_X86_CODE_FAR}
|
|
extra_param_offset = 0;
|
|
{$endif FPC_X86_CODE_FAR}
|
|
{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
|
|
extra_data_offset = 2;
|
|
{$else}
|
|
extra_data_offset = 0;
|
|
{$endif}
|
|
|
|
type
|
|
PFarByte = ^Byte;far;
|
|
PFarChar = ^Char;far;
|
|
PFarWord = ^Word;far;
|
|
PPFarChar = ^PFarChar;
|
|
|
|
var
|
|
__stktop : pointer;public name '__stktop';
|
|
__stkbottom : pointer;public name '__stkbottom';
|
|
__nearheap_start: pointer;public name '__nearheap_start';
|
|
__nearheap_end: pointer;public name '__nearheap_end';
|
|
dos_version:Word;public name 'dos_version';
|
|
dos_env_count:smallint;public name '__dos_env_count';
|
|
dos_argv0 : PFarChar;public name '__fpc_dos_argv0';
|
|
|
|
{$I registers.inc}
|
|
|
|
procedure Intr(IntNo: Byte; var Regs: Registers); external name 'FPC_INTR';
|
|
procedure MsDos(var Regs: Registers); external name 'FPC_MSDOS';
|
|
|
|
{ invokes int 21h with the carry flag set on entry; used for the LFN functions
|
|
to ensure that the carry flag is set on exit on older DOS versions which don't
|
|
support them }
|
|
procedure MsDos_Carry(var Regs: Registers); external name 'FPC_MSDOS_CARRY';
|
|
|
|
procedure InstallInterruptHandlers; external name 'FPC_INSTALL_INTERRUPT_HANDLERS';
|
|
procedure RestoreInterruptHandlers; external name 'FPC_RESTORE_INTERRUPT_HANDLERS';
|
|
|
|
function CheckNullArea: Boolean; external name 'FPC_CHECK_NULLAREA';
|
|
|
|
|
|
var
|
|
test_fpu_jmpbuf : jmp_buf;
|
|
|
|
Procedure InterceptInvalidInstruction;
|
|
begin
|
|
longjmp(test_fpu_jmpbuf, 1);
|
|
end;
|
|
|
|
{ Use msdos int21 set/get Interrupt address
|
|
to check if coprocessor is present }
|
|
|
|
{$define FPC_SYSTEM_HAS_SYSINITFPU}
|
|
Procedure SysInitFPU;
|
|
|
|
const
|
|
CR0_NE = $20;
|
|
CR0_NOT_NE = $FFFF - CR0_NE;
|
|
var
|
|
prevInt06 : FarPointer;
|
|
_newcr0_lw : word;
|
|
restore_old_int10 : boolean;
|
|
|
|
|
|
begin
|
|
restore_old_int10:=false;
|
|
asm
|
|
fninit
|
|
fldcw Default8087CW
|
|
fwait
|
|
end;
|
|
if Test8087 < 3 then { i8087/i80287 do not have "native" exception mode (CR0:NE) }
|
|
begin
|
|
restore_old_int10:=true;
|
|
end
|
|
else
|
|
begin
|
|
asm
|
|
push es
|
|
push ds
|
|
{ Get previous interrupt 06 handler }
|
|
mov ax, $3506
|
|
int $21
|
|
mov word [prevInt06],bx
|
|
mov dx,es
|
|
mov word [prevInt06+2],dx
|
|
{ Install local interrupt 06 handler }
|
|
{$ifdef FPC_MM_TINY}
|
|
{ Do not use SEG here, as this introduces a relocation that
|
|
is incompatible with COM executable generation }
|
|
mov dx, cs
|
|
{$else FPC_MM_TINY}
|
|
mov dx, SEG InterceptInvalidInstruction
|
|
{$endif FPC_MM_TINY}
|
|
mov ds, dx
|
|
mov dx, Offset InterceptInvalidInstruction
|
|
mov ax, $2506
|
|
int $21
|
|
pop ds
|
|
pop es
|
|
end;
|
|
if setjmp(test_fpu_jmpbuf)=0 then
|
|
begin
|
|
asm
|
|
db $0f, $20, $c0 { mov eax,cr0 }
|
|
{ Reset CR0 Numeric Error bit,
|
|
to trigger IRQ13 - interrupt $75,
|
|
and thus avoid the generation of a $10 trap
|
|
which iterferes with video interrupt handler }
|
|
and ax,CR0_NOT_NE
|
|
db $0f, $22, $c0 { mov cr0,eax }
|
|
end;
|
|
//writeln(stderr,'Change of cr0 succeeded');
|
|
// Test that NE bit is indeed reset
|
|
asm
|
|
db $0f, $20, $c0 { mov eax,cr0 }
|
|
mov _newcr0_lw, ax
|
|
end;
|
|
if (_newcr0_lw and CR0_NE) = 0 then
|
|
restore_old_int10:=true;
|
|
|
|
end
|
|
else
|
|
begin
|
|
//writeln(stderr,'Change of cr0 failed');
|
|
end;
|
|
{ Restore previous interrupt 06 handler }
|
|
asm
|
|
push ds
|
|
mov ax, $2506
|
|
lds dx,[prevInt06]
|
|
int $21
|
|
pop ds
|
|
end;
|
|
end;
|
|
{ Special handler of interrupt $10
|
|
not needed anymore
|
|
Restore previous interrupt $10 handler }
|
|
{$ifndef TEST_FPU_INT10}
|
|
if restore_old_int10 then
|
|
asm
|
|
push ds
|
|
mov ax, $2510
|
|
lds dx,[SaveInt10]
|
|
int $21
|
|
pop ds
|
|
end;
|
|
{$endif ndef TEST_FPU_INT10}
|
|
end;
|
|
|
|
{$I system.inc}
|
|
|
|
{$I tinyheap.inc}
|
|
|
|
{$I ports.inc}
|
|
|
|
procedure DebugWrite(const S: string);
|
|
begin
|
|
asm
|
|
{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
|
|
push ds
|
|
lds si, S
|
|
{$else}
|
|
mov si, S
|
|
{$endif}
|
|
{$ifdef FPC_ENABLED_CLD}
|
|
cld
|
|
{$endif FPC_ENABLED_CLD}
|
|
lodsb
|
|
mov cl, al
|
|
xor ch, ch
|
|
jcxz @@zero_length
|
|
mov ah, 2
|
|
|
|
@@1:
|
|
lodsb
|
|
mov dl, al
|
|
int 21h
|
|
loop @@1
|
|
@@zero_length:
|
|
{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
|
|
pop ds
|
|
{$endif}
|
|
end ['ax','bx','cx','dx','si','di'];
|
|
end;
|
|
|
|
procedure DebugWriteLn(const S: string);
|
|
begin
|
|
DebugWrite(S);
|
|
DebugWrite(#13#10);
|
|
end;
|
|
|
|
{*****************************************************************************
|
|
ParamStr/Randomize
|
|
*****************************************************************************}
|
|
|
|
var
|
|
internal_envp : PPFarChar = nil;
|
|
|
|
procedure setup_environment;
|
|
var
|
|
env_count : smallint;
|
|
cp, dos_env: PFarChar;
|
|
begin
|
|
env_count:=0;
|
|
dos_env:=Ptr(MemW[PrefixSeg:$2C], 0);
|
|
cp:=dos_env;
|
|
while cp^<>#0 do
|
|
begin
|
|
inc(env_count);
|
|
while (cp^ <> #0) do
|
|
inc(cp); { skip to NUL }
|
|
inc(cp); { skip to next character }
|
|
end;
|
|
internal_envp := getmem((env_count+1) * sizeof(PFarChar));
|
|
cp:=dos_env;
|
|
env_count:=0;
|
|
while cp^<>#0 do
|
|
begin
|
|
internal_envp[env_count] := cp;
|
|
inc(env_count);
|
|
while (cp^ <> #0) do
|
|
inc(cp); { skip to NUL }
|
|
inc(cp); { skip to next character }
|
|
end;
|
|
internal_envp[env_count]:=nil;
|
|
dos_env_count := env_count;
|
|
if dos_version >= $300 then
|
|
begin
|
|
if cp=dos_env then
|
|
inc(cp);
|
|
inc(cp, 3);
|
|
dos_argv0 := cp;
|
|
end
|
|
else
|
|
dos_argv0 := nil;
|
|
end;
|
|
|
|
function envp:PPFarChar;public name '__fpc_envp';
|
|
begin
|
|
if not assigned(internal_envp) then
|
|
setup_environment;
|
|
envp:=internal_envp;
|
|
end;
|
|
|
|
|
|
procedure setup_arguments;
|
|
var
|
|
I: SmallInt;
|
|
pc: PChar;
|
|
pfc: PFarChar;
|
|
quote: Char;
|
|
count: SmallInt;
|
|
arglen, argv0len: SmallInt;
|
|
argblock: PChar;
|
|
arg: PChar;
|
|
doscmd : string[129]; { Dos commandline copied from PSP, max is 128 chars +1 for terminating zero }
|
|
begin
|
|
{ force environment to be setup so dos_argv0 is loaded }
|
|
envp;
|
|
{ load commandline from psp }
|
|
SetLength(doscmd, Mem[PrefixSeg:$80]);
|
|
for I := 1 to length(doscmd) do
|
|
doscmd[I] := Chr(Mem[PrefixSeg:$80+I]);
|
|
doscmd[length(doscmd)+1]:=#0;
|
|
{$IfDef SYSTEM_DEBUG_STARTUP}
|
|
Writeln(stderr,'Dos command line is #',doscmd,'# size = ',length(doscmd));
|
|
{$EndIf }
|
|
{ find argv0len }
|
|
argv0len:=0;
|
|
if dos_argv0<>nil then
|
|
begin
|
|
pfc:=dos_argv0;
|
|
while pfc^<>#0 do
|
|
begin
|
|
Inc(argv0len);
|
|
Inc(pfc);
|
|
end;
|
|
end;
|
|
{ parse dos commandline }
|
|
pc:=@doscmd[1];
|
|
count:=1;
|
|
{ calc total arguments length and count }
|
|
arglen:=argv0len+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:=' ';
|
|
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 pchar(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 pchar(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;
|
|
inc(arglen); { for the null terminator }
|
|
inc(count);
|
|
end;
|
|
{ set argc and allocate argv }
|
|
argc:=count;
|
|
argv:=AllocMem((count+1)*SizeOf(PChar));
|
|
{ allocate a single memory block for all arguments }
|
|
argblock:=GetMem(arglen);
|
|
{ create argv[0] }
|
|
argv[0]:=argblock;
|
|
arg:=argblock;
|
|
if dos_argv0<>nil then
|
|
begin
|
|
pfc:=dos_argv0;
|
|
while pfc^<>#0 do
|
|
begin
|
|
arg^:=pfc^;
|
|
Inc(arg);
|
|
Inc(pfc);
|
|
end;
|
|
end;
|
|
arg^:=#0;
|
|
Inc(arg);
|
|
|
|
pc:=@doscmd[1];
|
|
count:=1;
|
|
while pc^<>#0 do
|
|
begin
|
|
{ skip leading spaces }
|
|
while pc^ in [#1..#32] do
|
|
inc(pc);
|
|
if pc^=#0 then
|
|
break;
|
|
{ copy argument }
|
|
argv[count]:=arg;
|
|
quote:=' ';
|
|
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 pchar(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 pchar(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;
|
|
Inc(arg);
|
|
{$IfDef SYSTEM_DEBUG_STARTUP}
|
|
Writeln(stderr,'dos arg ',count,' #',strlen(argv[count]),'#',argv[count],'#');
|
|
{$EndIf SYSTEM_DEBUG_STARTUP}
|
|
inc(count);
|
|
end;
|
|
end;
|
|
|
|
|
|
function paramcount : longint;
|
|
begin
|
|
if argv=nil then
|
|
setup_arguments;
|
|
paramcount := argc - 1;
|
|
end;
|
|
|
|
|
|
function paramstr(l : longint) : string;
|
|
begin
|
|
if argv=nil then
|
|
setup_arguments;
|
|
if (l>=0) and (l+1<=argc) then
|
|
paramstr:=strpas(argv[l])
|
|
else
|
|
paramstr:='';
|
|
end;
|
|
|
|
|
|
procedure randomize;
|
|
var
|
|
hl : longint;
|
|
regs : Registers;
|
|
begin
|
|
regs.AH:=$2C;
|
|
MsDos(regs);
|
|
hl:=regs.DX;
|
|
randseed:=hl*$10000+ regs.CX;
|
|
end;
|
|
|
|
{*****************************************************************************
|
|
System Dependent Exit code
|
|
*****************************************************************************}
|
|
|
|
procedure system_exit;
|
|
var
|
|
h : byte;
|
|
begin
|
|
RestoreInterruptHandlers;
|
|
for h:=0 to max_files-1 do
|
|
if openfiles[h] then
|
|
begin
|
|
{$ifdef SYSTEMDEBUG}
|
|
writeln(stderr,'file ',h,' "',opennames[h],'" not closed at exit');
|
|
{$endif SYSTEMDEBUG}
|
|
if h>=5 then
|
|
do_close(h);
|
|
end;
|
|
{$ifndef FPC_MM_TINY}
|
|
if not CheckNullArea then
|
|
writeln(stderr, 'Nil pointer assignment');
|
|
{$endif FPC_MM_TINY}
|
|
asm
|
|
mov al, byte [exitcode]
|
|
mov ah, 4Ch
|
|
int 21h
|
|
end;
|
|
end;
|
|
|
|
{*****************************************************************************
|
|
SystemUnit Initialization
|
|
*****************************************************************************}
|
|
|
|
procedure InitDosHeap;
|
|
type
|
|
{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
|
|
TPointerArithmeticType = HugePointer;
|
|
{$else}
|
|
TPointerArithmeticType = Pointer;
|
|
{$endif}
|
|
begin
|
|
RegisterTinyHeapBlock_Simple_Prealigned(__nearheap_start, TPointerArithmeticType(__nearheap_end) - TPointerArithmeticType(__nearheap_start));
|
|
end;
|
|
|
|
function CheckLFN:boolean;
|
|
var
|
|
regs : Registers;
|
|
RootName : pchar;
|
|
buf : array [0..31] of char;
|
|
begin
|
|
{ Check LFN API on drive c:\ }
|
|
RootName:='C:\';
|
|
{ Call 'Get Volume Information' ($71A0) }
|
|
regs.AX:=$71a0;
|
|
regs.ES:=Seg(buf);
|
|
regs.DI:=Ofs(buf);
|
|
regs.CX:=32;
|
|
regs.DS:=Seg(RootName^);
|
|
regs.DX:=Ofs(RootName^);
|
|
MsDos_Carry(regs);
|
|
{ If carryflag=0 and LFN API bit in ebx is set then use Long file names }
|
|
CheckLFN:=(regs.Flags and fCarry=0) and (regs.BX and $4000=$4000);
|
|
end;
|
|
|
|
procedure SysInitStdIO;
|
|
begin
|
|
OpenStdIO(Input,fmInput,StdInputHandle);
|
|
OpenStdIO(Output,fmOutput,StdOutputHandle);
|
|
OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
|
|
{$ifndef FPC_STDOUT_TRUE_ALIAS}
|
|
OpenStdIO(StdOut,fmOutput,StdOutputHandle);
|
|
OpenStdIO(StdErr,fmOutput,StdErrorHandle);
|
|
{$endif FPC_STDOUT_TRUE_ALIAS}
|
|
end;
|
|
|
|
function GetProcessID: SizeUInt;
|
|
begin
|
|
GetProcessID := PrefixSeg;
|
|
end;
|
|
|
|
function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
|
|
begin
|
|
result := stklen;
|
|
end;
|
|
|
|
begin
|
|
StackBottom := __stkbottom;
|
|
StackLength := __stktop - __stkbottom;
|
|
InstallInterruptHandlers;
|
|
DetectFPU;
|
|
if Test8087>0 then
|
|
SysInitFPU;
|
|
{ To be set if this is a GUI or console application }
|
|
IsConsole := TRUE;
|
|
{$ifdef FPC_HAS_FEATURE_DYNLIBS}
|
|
{ If dynlibs feature is disabled,
|
|
IsLibrary is a constant, which can thus not be set to a value }
|
|
{ To be set if this is a library and not a program }
|
|
IsLibrary := FALSE;
|
|
{$endif def FPC_HAS_FEATURE_DYNLIBS}
|
|
{ Setup heap }
|
|
InitDosHeap;
|
|
SysInitExceptions;
|
|
{$ifdef FPC_HAS_FEATURE_UNICODESTRINGS}
|
|
initunicodestringmanager;
|
|
{$endif def FPC_HAS_FEATURE_UNICODESTRINGS}
|
|
{ Setup stdin, stdout and stderr }
|
|
SysInitStdIO;
|
|
{ Setup environment and arguments }
|
|
{ Done on request only Setup_Environment; }
|
|
{ Done on request only Setup_Arguments; }
|
|
{$ifndef RTLLITE}
|
|
{ Use LFNSupport LFN }
|
|
LFNSupport:=CheckLFN;
|
|
if LFNSupport then
|
|
begin
|
|
FileNameCasePreserving:=true;
|
|
AllFilesMask := '*';
|
|
end
|
|
else
|
|
{$endif ndef RTLLITE}
|
|
AllFilesMask := '*.*';
|
|
{ Reset IO Error }
|
|
InOutRes:=0;
|
|
{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
InitSystemThreads;
|
|
{$endif}
|
|
end.
|