mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-05 12:18:30 +02:00
327 lines
8.4 KiB
ObjectPascal
327 lines
8.4 KiB
ObjectPascal
{
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 2004-2006 by Karoly Balogh
|
|
|
|
AROS conversion
|
|
Copyright (c) 2011 by Marcus Sackrow
|
|
|
|
System unit for AROS
|
|
|
|
Uses parts of the Free Pascal 1.0.x for Commodore Amiga/68k port
|
|
by Carl Eric Codere and Nils Sjoholm
|
|
|
|
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
|
|
|
|
{$define FPC_IS_SYSTEM}
|
|
|
|
{$I systemh.inc}
|
|
{$I osdebugh.inc}
|
|
|
|
const
|
|
LineEnding = #10;
|
|
LFNSupport = True;
|
|
DirectorySeparator = '/';
|
|
DriveSeparator = ':';
|
|
ExtensionSeparator = '.';
|
|
PathSeparator = ';';
|
|
AllowDirectorySeparators : set of AnsiChar = ['\','/'];
|
|
AllowDriveSeparators : set of AnsiChar = [':'];
|
|
maxExitCode = 255;
|
|
MaxPathLen = 256;
|
|
AllFilesMask = '#?';
|
|
|
|
const
|
|
UnusedHandle : THandle = 0;
|
|
StdInputHandle : THandle = 0;
|
|
StdOutputHandle : THandle = 0;
|
|
StdErrorHandle : THandle = 0;
|
|
|
|
FileNameCaseSensitive : Boolean = False;
|
|
FileNameCasePreserving: boolean = True;
|
|
CtrlZMarksEOF: Boolean = false; (* #26 not considered as end of file *)
|
|
|
|
sLineBreak = LineEnding;
|
|
DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
|
|
|
|
BreakOn : Boolean = True;
|
|
|
|
|
|
|
|
var
|
|
AOS_ExecBase : Pointer; external name '_ExecBase';
|
|
AOS_DOSBase : Pointer;
|
|
AOS_UtilityBase: Pointer;
|
|
AROS_ThreadLib : Pointer; public name 'AROS_THREADLIB';
|
|
|
|
ASYS_heapPool : Pointer; { pointer for the OS pool for growing the heap }
|
|
ASYS_fileSemaphore: Pointer; { mutex semaphore for filelist access arbitration }
|
|
ASYS_origDir : PtrInt; { original directory on startup }
|
|
AOS_wbMsg : Pointer;
|
|
AOS_ConName : PAnsiChar ='CON:10/30/620/100/FPC Console Output/AUTO/CLOSE/WAIT';
|
|
AOS_ConHandle: THandle;
|
|
|
|
SysDebugBase: Pointer = nil;
|
|
|
|
argc: LongInt;
|
|
argv: PPAnsiChar;
|
|
envp: PPAnsiChar;
|
|
killed : Boolean = False;
|
|
|
|
function GetLibAdress(Base: Pointer; Offset: LongInt): Pointer;
|
|
procedure Debug(s: shortstring);
|
|
procedure Debugln(s: shortstring);
|
|
procedure EnableBackTraceStr;
|
|
|
|
implementation
|
|
|
|
{$I system.inc}
|
|
{$I osdebug.inc}
|
|
type
|
|
PWBArg = ^TWBArg;
|
|
TWBArg = record
|
|
wa_Lock : BPTR; { a lock descriptor }
|
|
wa_Name : PAnsiChar; { a string relative to that lock }
|
|
end;
|
|
|
|
WBArgList = array[1..MaxInt] of TWBArg; { Only 1..smNumArgs are valid }
|
|
PWBArgList = ^WBArgList;
|
|
|
|
|
|
PWBStartup = ^TWBStartup;
|
|
TWBStartup = record
|
|
sm_Message : TMessage; { a standard message structure }
|
|
sm_Process : Pointer; { the process descriptor for you }
|
|
sm_Segment : Pointer; { a descriptor for your code }
|
|
sm_NumArgs : Longint; { the number of elements in ArgList }
|
|
sm_ToolWindow : Pointer; { description of window }
|
|
sm_ArgList : PWBArgList; { the arguments themselves }
|
|
end;
|
|
|
|
{*****************************************************************************
|
|
Misc. System Dependent Functions
|
|
*****************************************************************************}
|
|
|
|
procedure haltproc(e:longint); cdecl; external name '_haltproc';
|
|
|
|
procedure System_exit;
|
|
var
|
|
oldDirLock: PtrInt;
|
|
begin
|
|
if Killed then
|
|
Exit;
|
|
Killed := True;
|
|
|
|
{ Dispose the thread init/exit chains }
|
|
CleanupThreadProcChain(threadInitProcList);
|
|
CleanupThreadProcChain(threadExitProcList);
|
|
|
|
{ Closing opened files }
|
|
CloseList(ASYS_fileList);
|
|
{ Changing back to original directory if changed }
|
|
if ASYS_OrigDir <> 0 then begin
|
|
oldDirLock:=CurrentDir(ASYS_origDir);
|
|
{ unlock our lock if its safe, so we won't leak the lock }
|
|
if (oldDirLock<>0) and (oldDirLock<>ASYS_origDir) then
|
|
Unlock(oldDirLock);
|
|
end;
|
|
// debug lib
|
|
if SysDebugBase <> nil then
|
|
CloseLibrary(SysDebugBase);
|
|
SysDebugBase := nil;
|
|
// utility
|
|
if AOS_UtilityBase <> nil then
|
|
CloseLibrary(AOS_UtilityBase);
|
|
// Heap
|
|
if ASYS_heapPool <> nil then
|
|
DeletePool(ASYS_heapPool);
|
|
AOS_UtilityBase := nil;
|
|
ASYS_HeapPool := nil;
|
|
// dos
|
|
if AOS_DOSBase<>nil then
|
|
CloseLibrary(AOS_DOSBase);
|
|
AOS_DOSBase := nil;
|
|
//
|
|
if AOS_wbMsg <> nil then
|
|
begin
|
|
// forbid -> Amiga RKM Libraries Manual
|
|
Forbid();
|
|
// Reply WBStartupMessage
|
|
ReplyMsg(AOS_wbMsg);
|
|
end;
|
|
//
|
|
HaltProc(ExitCode);
|
|
end;
|
|
|
|
{*****************************************************************************
|
|
Parameterhandling
|
|
as include in amicommon
|
|
*****************************************************************************}
|
|
|
|
{$I paramhandling.inc}
|
|
|
|
{*****************************************************************************
|
|
Randomize
|
|
*****************************************************************************}
|
|
|
|
{ set randseed to a new pseudo random value }
|
|
procedure Randomize;
|
|
var
|
|
tmpTime: TDateStamp;
|
|
begin
|
|
DateStamp(@tmpTime);
|
|
randseed := tmpTime.ds_tick;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{ AmigaOS specific startup }
|
|
procedure SysInitAmigaOS;
|
|
var
|
|
self: PProcess;
|
|
begin
|
|
self := PProcess(FindTask(nil));
|
|
if self^.pr_CLI = 0 then begin
|
|
{ if we're running from Ambient/Workbench, we catch its message }
|
|
WaitPort(@self^.pr_MsgPort);
|
|
AOS_wbMsg:=GetMsg(@self^.pr_MsgPort);
|
|
end;
|
|
|
|
AOS_DOSBase := OpenLibrary('dos.library', 0);
|
|
if AOS_DOSBase = nil then
|
|
Halt(1);
|
|
AOS_UtilityBase := OpenLibrary('utility.library', 0);
|
|
if AOS_UtilityBase = nil then
|
|
Halt(1);
|
|
|
|
{ Creating the memory pool for growing heap }
|
|
ASYS_heapPool := CreatePool(MEMF_ANY or MEMF_SEM_PROTECTED, growheapsize2, growheapsize1);
|
|
if ASYS_heapPool = nil then
|
|
Halt(1);
|
|
|
|
{ Initialize semaphore for filelist access arbitration }
|
|
ASYS_fileSemaphore:=AllocPooled(ASYS_heapPool,sizeof(TSignalSemaphore));
|
|
if ASYS_fileSemaphore = nil then
|
|
Halt(1);
|
|
InitSemaphore(ASYS_fileSemaphore);
|
|
|
|
if AOS_wbMsg = nil then begin
|
|
StdInputHandle := THandle(dosInput);
|
|
StdOutputHandle := THandle(dosOutput);
|
|
StdErrorHandle := THandle(DosError1);
|
|
end else begin
|
|
AOS_ConHandle := Open(AOS_ConName, MODE_OLDFILE);
|
|
if AOS_ConHandle <> 0 then begin
|
|
StdInputHandle := AOS_ConHandle;
|
|
StdOutputHandle := AOS_ConHandle;
|
|
StdErrorHandle := AOS_ConHandle;
|
|
end else
|
|
Halt(1);
|
|
end;
|
|
end;
|
|
|
|
function AROSBackTraceStr(Addr: CodePointer): ShortString;
|
|
const
|
|
DL_Dummy = TAG_USER + $03e00000;
|
|
DL_ModuleName = DL_Dummy + 1;
|
|
DL_SymbolName = DL_Dummy + 7;
|
|
var
|
|
SymName, ModName: PAnsiChar;
|
|
Tags: array[0..5] of PtrUInt;
|
|
s: AnsiString;
|
|
Res: AnsiString;
|
|
begin
|
|
if Assigned(SysDebugBase) then
|
|
begin
|
|
ModName := nil;
|
|
SymName := nil;
|
|
Tags[0] := DL_Modulename;
|
|
Tags[1] := PtrUInt(@ModName);
|
|
Tags[2] := DL_SymbolName;
|
|
Tags[3] := PtrUInt(@SymName);
|
|
Tags[4] := 0;
|
|
Tags[5] := 0;
|
|
DecodeLocation(Addr, @Tags[0]);
|
|
s := '-';
|
|
if not Assigned(ModName) then
|
|
ModName := @S[1];
|
|
if not Assigned(SymName) then
|
|
SymName := @S[1];
|
|
Res := ' $' + HexStr(Addr) + ' ' + ModName + ' ' + SymName;
|
|
AROSBackTraceStr := Copy(Res, 1, 254);
|
|
end
|
|
else
|
|
begin
|
|
AROSBackTraceStr := ' $' + HexStr(Addr) + ' - ';
|
|
end;
|
|
end;
|
|
|
|
procedure EnableBackTraceStr;
|
|
begin
|
|
if not Assigned(SysDebugBase) then
|
|
begin
|
|
SysDebugBase := OpenLibrary('debug.library', 0);
|
|
if Assigned(SysDebugBase) then
|
|
BackTraceStrFunc := @AROSBackTraceStr;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure SysInitStdIO;
|
|
begin
|
|
OpenStdIO(Input,fmInput,StdInputHandle);
|
|
OpenStdIO(Output,fmOutput,StdOutputHandle);
|
|
OpenStdIO(StdOut,fmOutput,StdOutputHandle);
|
|
OpenStdIO(StdErr,fmOutput,StdErrorHandle);
|
|
end;
|
|
|
|
function GetProcessID: SizeUInt;
|
|
begin
|
|
GetProcessID := SizeUInt(FindTask(NIL));
|
|
end;
|
|
|
|
function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
|
|
begin
|
|
result := stklen;
|
|
end;
|
|
|
|
begin
|
|
IsConsole := TRUE;
|
|
SysResetFPU;
|
|
if not (IsLibrary) then
|
|
SysInitFPU;
|
|
StackLength := CheckInitialStkLen(InitialStkLen);
|
|
StackBottom := Sptr - StackLength;
|
|
{ OS specific startup }
|
|
AOS_wbMsg := nil;
|
|
ASYS_origDir := 0;
|
|
ASYS_fileList := nil;
|
|
envp := nil;
|
|
SysInitAmigaOS;
|
|
{ Set up signals handlers }
|
|
//InstallSignals;
|
|
{ Setup heap }
|
|
InitHeap;
|
|
SysInitExceptions;
|
|
initunicodestringmanager;
|
|
{ Setup stdin, stdout and stderr }
|
|
SysInitStdIO;
|
|
{ Reset IO Error }
|
|
InOutRes:=0;
|
|
{ Arguments }
|
|
GenerateArgs;
|
|
InitSystemThreads;
|
|
InitSystemDynLibs;
|
|
end.
|