123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2020 by Karoly Balogh
- System unit for the Sinclair QL
- 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}
- {$define FPC_STDOUT_TRUE_ALIAS}
- {$define FPC_ANSI_TEXTFILEREC}
- {$define FPC_QL_USE_OSHEAP}
- {$ifdef FPC_QL_USE_OSHEAP}
- {$define HAS_MEMORYMANAGER}
- {$endif FPC_QL_USE_OSHEAP}
- {$i systemh.inc}
- {Platform specific information}
- const
- LineEnding = #10;
- LFNSupport = false;
- CtrlZMarksEOF: boolean = false; (* #26 not considered as end of file *)
- DirectorySeparator = '\';
- DriveSeparator = ':';
- ExtensionSeparator = '.';
- PathSeparator = ';';
- AllowDirectorySeparators : set of char = ['\','/'];
- AllowDriveSeparators : set of char = [':'];
- FileNameCaseSensitive = false;
- FileNameCasePreserving = false;
- maxExitCode = 255;
- MaxPathLen = 255;
- AllFilesMask = '*.*';
- sLineBreak = LineEnding;
- DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
- const
- UnusedHandle = -1;
- StdInputHandle: longint = UnusedHandle;
- StdOutputHandle: longint = UnusedHandle;
- StdErrorHandle: longint = UnusedHandle;
- var
- QL_ChannelIDNum : word;
- QL_ChannelIDs: pdword;
- QL_CommandLineLen : word;
- QL_CommandLine : pchar;
- argv: PPChar;
- argc: Longint;
- {$if defined(FPUSOFT)}
- {$define fpc_softfpu_interface}
- {$i softfpu.pp}
- {$undef fpc_softfpu_interface}
- {$endif defined(FPUSOFT)}
- type
- QLConHandle = record
- inputHandle: longint;
- outputHandle: longint;
- errorHandle: longint;
- userData: pointer;
- end;
- function SetQLJobName(const s: string): longint;
- function GetQLJobName: string;
- function GetQLJobNamePtr: pointer;
- procedure SetQLDefaultConExitMessage(const msg: PChar);
- implementation
- {$define FPC_SYSTEM_HAS_STACKTOP}
- {$define FPC_SYSTEM_HAS_BACKTRACESTR}
- {$if defined(FPUSOFT)}
- {$define fpc_softfpu_implementation}
- {$define softfpu_compiler_mul32to64}
- {$define softfpu_inline}
- {$i softfpu.pp}
- {$undef fpc_softfpu_implementation}
- { we get these functions and types from the softfpu code }
- {$define FPC_SYSTEM_HAS_float64}
- {$define FPC_SYSTEM_HAS_float32}
- {$define FPC_SYSTEM_HAS_flag}
- {$define FPC_SYSTEM_HAS_extractFloat64Frac0}
- {$define FPC_SYSTEM_HAS_extractFloat64Frac1}
- {$define FPC_SYSTEM_HAS_extractFloat64Exp}
- {$define FPC_SYSTEM_HAS_extractFloat64Sign}
- {$define FPC_SYSTEM_HAS_ExtractFloat32Frac}
- {$define FPC_SYSTEM_HAS_extractFloat32Exp}
- {$define FPC_SYSTEM_HAS_extractFloat32Sign}
- {$endif defined(FPUSOFT)}
- {$i system.inc}
- {$ifdef FPC_QL_USE_OSHEAP}
- {$i osheap.inc}
- {$endif FPC_QL_USE_OSHEAP}
- function GetProcessID:SizeUInt;
- begin
- GetProcessID := mt_inf(nil, nil);
- end;
- {*****************************************************************************
- ParamStr
- *****************************************************************************}
- var
- args: PChar;
- { number of args }
- function ParamCount: LongInt;
- begin
- ParamCount:=argc;
- end;
- { argument number l }
- function ParamStr(l: LongInt): string;
- begin
- if (l >= 0) and (l <= argc) then
- ParamStr:=argv[l]
- else
- ParamStr:='';
- end;
- procedure SysInitParamsAndEnv;
- var
- i,j : longint;
- c : char;
- argv_size : longint;
- const
- word_separators=[' ',#0];
- begin
- argc:=0;
- argv:=nil;
- args:=GetMem(QL_CommandLineLen+1);
- if not assigned(args) then
- exit;
- Move(QL_CommandLine^,args^,QL_CommandLineLen);
- args[QL_CommandLineLen]:=#0;
- i:=0;
- c:=' ';
- while args[i]<>#0 do
- begin
- if (c in word_separators) and not (args[i] in word_separators) then
- inc(argc);
- c:=args[i];
- inc(i);
- end;
- { +2 is because argv[0] should be program name,
- and argv[argc+1] is argv array terminator }
- argv:=GetMem((argc+2)*sizeof(pointer));
- if not assigned(argv) then
- begin
- argc:=0;
- exit;
- end;
- argv[argc+1]:=nil;
- { FIX ME: for now the 0th argument (program name) is just always empty }
- argv[0]:=#0;
- i:=0;
- j:=1;
- c:=' ';
- while args[i]<>#0 do
- begin
- if (c in word_separators) and not (args[i] in word_separators) then
- begin
- argv[j]:=@args[i];
- inc(j);
- end;
- c:=args[i];
- if (c in word_separators) then
- args[i]:=#0;
- inc(i);
- end;
- end;
- procedure randomize;
- begin
- { Get the current date/time }
- randseed:=mt_rclck;
- end;
- {*****************************************************************************
- Platform specific custom calls
- *****************************************************************************}
- procedure PrintStr(ch: longint; const s: shortstring);
- begin
- io_sstrg(ch,-1,@s[1],ord(s[0]));
- end;
- procedure DebugStr(const s: shortstring); public name '_dbgstr';
- var
- i: longint;
- begin
- PrintStr(stdOutputHandle,s);
- for i:=0 to 10000 do begin end;
- end;
- var
- start_proc: byte; external name '_start';
- { WARNING! if you change this value, make sure there's enough
- buffer space for the job name in the startup code! }
- const
- JOB_NAME_MAX_LEN = 48;
- function SetQLJobName(const s: string): longint;
- var
- len: longint;
- begin
- SetQLJobName:=-1;
- if pword(@start_proc)[3] = $4afb then
- begin
- len:=length(s);
- if len > JOB_NAME_MAX_LEN then
- len:=JOB_NAME_MAX_LEN;
- Move(s[1],pword(@start_proc)[5],len);
- pword(@start_proc)[4]:=len;
- SetQLJobName:=len;
- end;
- end;
- function GetQLJobName: string;
- var
- len: longint;
- begin
- GetQLJobName:='';
- if pword(@start_proc)[3] = $4afb then
- begin
- len:=pword(@start_proc)[4];
- if len <= JOB_NAME_MAX_LEN then
- begin
- SetLength(GetQLJobName,len);
- Move(pword(@start_proc)[5],GetQLJobName[1],len);
- end;
- end;
- end;
- function GetQLJobNamePtr: pointer;
- begin
- GetQLJobNamePtr:=nil;
- if pword(@start_proc)[3] = $4afb then
- begin
- GetQLJobNamePtr:=@pword(@start_proc)[4];
- end;
- end;
- const
- QLDefaultConExitMessage: PChar = 'Press any key to exit';
- procedure SetQLDefaultConExitMessage(const msg: PChar);
- begin
- QLDefaultConExitMessage:=msg;
- end;
- function QLOpenCon(var console: QLConHandle): boolean; weakexternal name 'QLOpenCon';
- procedure QLCloseCon(var console: QLConHandle); weakexternal name 'QLCloseCon';
- function DefaultQLOpenCon(var console: QLConHandle): boolean;
- var
- r: TQLRect;
- begin
- DefaultQLOpenCon:=false;
- with console do
- begin
- inputHandle:=io_open('con_',Q_OPEN);
- if inputHandle <= 0 then
- exit;
- outputHandle:=inputHandle;
- errorHandle:=inputHandle;
- userData:=nil;
- r.q_width:=512;
- r.q_height:=256;
- r.q_x:=0;
- r.q_y:=0;
- sd_wdef(outputHandle,-1,2,1,@r);
- sd_clear(outputHandle,-1);
- end;
- DefaultQLOpenCon:=true;
- end;
- procedure DefaultQLCloseCon(var console: QLConHandle);
- begin
- with console do
- begin
- if assigned(QLDefaultConExitMessage) and (length(QLDefaultConExitMessage) > 0) then
- begin
- io_sstrg(outputHandle, -1, QLDefaultConExitMessage, length(QLDefaultConExitMessage));
- io_fbyte(inputHandle, -1);
- end;
- end;
- end;
- {*****************************************************************************
- System Dependent Entry code
- *****************************************************************************}
- var
- jobStackDataPtr: pointer; external name '__stackpointer_on_entry';
- program_name: shortstring; external name '__fpc_program_name';
- QLCon: QLConHandle;
- QLConOpen: boolean;
- { QL/QDOS specific startup }
- procedure SysInitQDOS;
- begin
- QL_ChannelIDNum:=pword(jobStackDataPtr)[0];
- QL_ChannelIDs:=@pword(jobStackDataPtr)[1];
- QL_CommandLineLen:=pword(@QL_ChannelIDs[QL_ChannelIDNum])[0];
- QL_CommandLine:=@pword(@QL_ChannelIDs[QL_ChannelIDNum])[1];
- SetQLJobName(program_name);
- if assigned(@QLOpenCon) then
- QLConOpen:=QLOpenCon(QLCon)
- else
- QLConOpen:=DefaultQLOpenCon(QLCon);
- if not QLConOpen then
- halt(1);
- with QLCon do
- begin
- stdInputHandle:=inputHandle;
- stdOutputHandle:=outputHandle;
- stdErrorHandle:=errorHandle;
- end;
- end;
- {*****************************************************************************
- System Dependent Exit code
- *****************************************************************************}
- procedure haltproc(e:longint); external name '_haltproc';
- procedure system_exit;
- begin
- if assigned(args) then
- FreeMem(args);
- if assigned(argv) then
- FreeMem(argv);
- if QLConOpen then
- begin
- if assigned(@QLCloseCon) then
- QLCloseCon(QLCon)
- else
- DefaultQLCloseCon(QLCon);
- end;
- stdInputHandle:=UnusedHandle;
- stdOutputHandle:=UnusedHandle;
- stdErrorHandle:=UnusedHandle;
- haltproc(exitcode);
- end;
- {*****************************************************************************
- System Unit Initialization
- *****************************************************************************}
- 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 CheckInitialStkLen (StkLen: SizeUInt): SizeUInt;
- begin
- CheckInitialStkLen := StkLen;
- end;
- begin
- StackLength := CheckInitialStkLen (InitialStkLen);
- StackBottom := StackTop - StackLength;
- StackMargin := min(align(StackLength div 20,2),STACK_MARGIN_MAX);
- { Initialize ExitProc }
- ExitProc:=Nil;
- SysInitQDOS;
- {$ifndef FPC_QL_USE_OSHEAP}
- { Setup heap }
- InitHeap;
- {$else FPC_QL_USE_OSHEAP}
- // InitOSHeap;
- {$endif FPC_QL_USE_OSHEAP}
- SysInitExceptions;
- {$ifdef FPC_HAS_FEATURE_UNICODESTRINGS}
- InitUnicodeStringManager;
- {$endif FPC_HAS_FEATURE_UNICODESTRINGS}
- { Setup stdin, stdout and stderr }
- SysInitStdIO;
- { Reset IO Error }
- InOutRes:=0;
- { Setup command line arguments }
- SysInitParamsAndEnv;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- InitSystemThreads;
- {$endif FPC_HAS_FEATURE_THREADING}
- end.
|