system.pp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2020 by Karoly Balogh
  4. System unit for the Sinclair QL
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit System;
  12. interface
  13. {$define FPC_IS_SYSTEM}
  14. {$define FPC_STDOUT_TRUE_ALIAS}
  15. {$define FPC_ANSI_TEXTFILEREC}
  16. {$define FPC_QL_USE_OSHEAP}
  17. {$ifdef FPC_QL_USE_OSHEAP}
  18. {$define HAS_MEMORYMANAGER}
  19. {$endif FPC_QL_USE_OSHEAP}
  20. {$i systemh.inc}
  21. {Platform specific information}
  22. const
  23. LineEnding = #10;
  24. LFNSupport = false;
  25. CtrlZMarksEOF: boolean = false; (* #26 not considered as end of file *)
  26. DirectorySeparator = '\';
  27. DriveSeparator = ':';
  28. ExtensionSeparator = '.';
  29. PathSeparator = ';';
  30. AllowDirectorySeparators : set of char = ['\','/'];
  31. AllowDriveSeparators : set of char = [':'];
  32. FileNameCaseSensitive = false;
  33. FileNameCasePreserving = false;
  34. maxExitCode = 255;
  35. MaxPathLen = 255;
  36. AllFilesMask = '*.*';
  37. sLineBreak = LineEnding;
  38. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
  39. const
  40. UnusedHandle = -1;
  41. StdInputHandle: longint = UnusedHandle;
  42. StdOutputHandle: longint = UnusedHandle;
  43. StdErrorHandle: longint = UnusedHandle;
  44. var
  45. QL_ChannelIDNum : word;
  46. QL_ChannelIDs: pdword;
  47. QL_CommandLineLen : word;
  48. QL_CommandLine : pchar;
  49. argv: PPChar;
  50. argc: Longint;
  51. {$if defined(FPUSOFT)}
  52. {$define fpc_softfpu_interface}
  53. {$i softfpu.pp}
  54. {$undef fpc_softfpu_interface}
  55. {$endif defined(FPUSOFT)}
  56. function SetQLJobName(const s: string): longint;
  57. function GetQLJobName: string;
  58. implementation
  59. {$if defined(FPUSOFT)}
  60. {$define fpc_softfpu_implementation}
  61. {$define softfpu_compiler_mul32to64}
  62. {$define softfpu_inline}
  63. {$i softfpu.pp}
  64. {$undef fpc_softfpu_implementation}
  65. { we get these functions and types from the softfpu code }
  66. {$define FPC_SYSTEM_HAS_float64}
  67. {$define FPC_SYSTEM_HAS_float32}
  68. {$define FPC_SYSTEM_HAS_flag}
  69. {$define FPC_SYSTEM_HAS_extractFloat64Frac0}
  70. {$define FPC_SYSTEM_HAS_extractFloat64Frac1}
  71. {$define FPC_SYSTEM_HAS_extractFloat64Exp}
  72. {$define FPC_SYSTEM_HAS_extractFloat64Sign}
  73. {$define FPC_SYSTEM_HAS_ExtractFloat32Frac}
  74. {$define FPC_SYSTEM_HAS_extractFloat32Exp}
  75. {$define FPC_SYSTEM_HAS_extractFloat32Sign}
  76. {$endif defined(FPUSOFT)}
  77. {$i system.inc}
  78. {$ifdef FPC_QL_USE_OSHEAP}
  79. {$i osheap.inc}
  80. {$endif FPC_QL_USE_OSHEAP}
  81. function GetProcessID:SizeUInt;
  82. begin
  83. GetProcessID := mt_inf(nil, nil);
  84. end;
  85. {*****************************************************************************
  86. ParamStr
  87. *****************************************************************************}
  88. var
  89. args: PChar;
  90. { number of args }
  91. function ParamCount: LongInt;
  92. begin
  93. ParamCount:=argc;
  94. end;
  95. { argument number l }
  96. function ParamStr(l: LongInt): string;
  97. begin
  98. if (l >= 0) and (l <= argc) then
  99. ParamStr:=argv[l]
  100. else
  101. ParamStr:='';
  102. end;
  103. procedure SysInitParamsAndEnv;
  104. var
  105. i,j : longint;
  106. c : char;
  107. argv_size : longint;
  108. const
  109. word_separators=[' ',#0];
  110. begin
  111. argc:=0;
  112. argv:=nil;
  113. args:=GetMem(QL_CommandLineLen+1);
  114. if not assigned(args) then
  115. exit;
  116. Move(QL_CommandLine^,args^,QL_CommandLineLen);
  117. args[QL_CommandLineLen]:=#0;
  118. i:=0;
  119. c:=' ';
  120. while args[i]<>#0 do
  121. begin
  122. if (c in word_separators) and not (args[i] in word_separators) then
  123. inc(argc);
  124. c:=args[i];
  125. inc(i);
  126. end;
  127. { +2 is because argv[0] should be program name,
  128. and argv[argc+1] is argv array terminator }
  129. argv:=GetMem((argc+2)*sizeof(pointer));
  130. if not assigned(argv) then
  131. begin
  132. argc:=0;
  133. exit;
  134. end;
  135. argv[argc+1]:=nil;
  136. { FIX ME: for now the 0th argument (program name) is just always empty }
  137. argv[0]:=#0;
  138. i:=0;
  139. j:=1;
  140. c:=' ';
  141. while args[i]<>#0 do
  142. begin
  143. if (c in word_separators) and not (args[i] in word_separators) then
  144. begin
  145. argv[j]:=@args[i];
  146. inc(j);
  147. end;
  148. c:=args[i];
  149. if (c in word_separators) then
  150. args[i]:=#0;
  151. inc(i);
  152. end;
  153. end;
  154. procedure randomize;
  155. begin
  156. { Get the current date/time }
  157. randseed:=mt_rclck;
  158. end;
  159. {*****************************************************************************
  160. Platform specific custom calls
  161. *****************************************************************************}
  162. procedure PrintStr(ch: longint; const s: shortstring);
  163. begin
  164. io_sstrg(ch,-1,@s[1],ord(s[0]));
  165. end;
  166. procedure DebugStr(const s: shortstring); public name '_dbgstr';
  167. var
  168. i: longint;
  169. begin
  170. PrintStr(stdOutputHandle,s);
  171. for i:=0 to 10000 do begin end;
  172. end;
  173. var
  174. start_proc: byte; external name '_start';
  175. { WARNING! if you change this value, make sure there's enough
  176. buffer space for the job name in the startup code! }
  177. const
  178. JOB_NAME_MAX_LEN = 48;
  179. function SetQLJobName(const s: string): longint;
  180. var
  181. len: longint;
  182. begin
  183. SetQLJobName:=-1;
  184. if pword(@start_proc)[3] = $4afb then
  185. begin
  186. len:=length(s);
  187. if len > JOB_NAME_MAX_LEN then
  188. len:=JOB_NAME_MAX_LEN;
  189. Move(s[1],pword(@start_proc)[5],len);
  190. pword(@start_proc)[4]:=len;
  191. SetQLJobName:=len;
  192. end;
  193. end;
  194. function GetQLJobName: string;
  195. var
  196. len: longint;
  197. begin
  198. GetQLJobName:='';
  199. if pword(@start_proc)[3] = $4afb then
  200. begin
  201. len:=pword(@start_proc)[4];
  202. if len <= JOB_NAME_MAX_LEN then
  203. begin
  204. SetLength(GetQLJobName,len);
  205. Move(pword(@start_proc)[5],GetQLJobName[1],len);
  206. end;
  207. end;
  208. end;
  209. {*****************************************************************************
  210. System Dependent Entry code
  211. *****************************************************************************}
  212. var
  213. jobStackDataPtr: pointer; external name '__job_stack_data_ptr';
  214. program_name: shortstring; external name '__fpc_program_name';
  215. { QL/QDOS specific startup }
  216. procedure SysInitQDOS;
  217. var
  218. r: TQLRect;
  219. begin
  220. QL_ChannelIDNum:=pword(jobStackDataPtr)[0];
  221. QL_ChannelIDs:=@pword(jobStackDataPtr)[1];
  222. QL_CommandLineLen:=pword(@QL_ChannelIDs[QL_ChannelIDNum])[0];
  223. QL_CommandLine:=@pword(@QL_ChannelIDs[QL_ChannelIDNum])[1];
  224. SetQLJobName(program_name);
  225. stdInputHandle:=io_open('con_',Q_OPEN);
  226. stdOutputHandle:=stdInputHandle;
  227. stdErrorHandle:=stdInputHandle;
  228. r.q_width:=512;
  229. r.q_height:=256;
  230. r.q_x:=0;
  231. r.q_y:=0;
  232. sd_wdef(stdInputHandle,-1,2,1,@r);
  233. sd_clear(stdInputHandle,-1);
  234. end;
  235. {*****************************************************************************
  236. System Dependent Exit code
  237. *****************************************************************************}
  238. procedure haltproc(e:longint); external name '_haltproc';
  239. procedure system_exit;
  240. const
  241. anyKey: string = 'Press any key to exit';
  242. begin
  243. if assigned(args) then
  244. FreeMem(args);
  245. if assigned(argv) then
  246. FreeMem(argv);
  247. io_sstrg(stdOutputHandle, -1, @anyKey[1], ord(anyKey[0]));
  248. io_fbyte(stdInputHandle, -1);
  249. stdInputHandle:=UnusedHandle;
  250. stdOutputHandle:=UnusedHandle;
  251. stdErrorHandle:=UnusedHandle;
  252. haltproc(exitcode);
  253. end;
  254. {*****************************************************************************
  255. System Unit Initialization
  256. *****************************************************************************}
  257. procedure SysInitStdIO;
  258. begin
  259. OpenStdIO(Input,fmInput,StdInputHandle);
  260. OpenStdIO(Output,fmOutput,StdOutputHandle);
  261. OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
  262. {$ifndef FPC_STDOUT_TRUE_ALIAS}
  263. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  264. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  265. {$endif FPC_STDOUT_TRUE_ALIAS}
  266. end;
  267. function CheckInitialStkLen (StkLen: SizeUInt): SizeUInt;
  268. begin
  269. CheckInitialStkLen := StkLen;
  270. end;
  271. begin
  272. StackLength := CheckInitialStkLen (InitialStkLen);
  273. { Initialize ExitProc }
  274. ExitProc:=Nil;
  275. SysInitQDOS;
  276. {$ifndef FPC_QL_USE_OSHEAP}
  277. { Setup heap }
  278. InitHeap;
  279. {$else FPC_QL_USE_OSHEAP}
  280. // InitOSHeap;
  281. {$endif FPC_QL_USE_OSHEAP}
  282. SysInitExceptions;
  283. {$ifdef FPC_HAS_FEATURE_UNICODESTRINGS}
  284. InitUnicodeStringManager;
  285. {$endif FPC_HAS_FEATURE_UNICODESTRINGS}
  286. { Setup stdin, stdout and stderr }
  287. SysInitStdIO;
  288. { Reset IO Error }
  289. InOutRes:=0;
  290. { Setup command line arguments }
  291. SysInitParamsAndEnv;
  292. {$ifdef FPC_HAS_FEATURE_THREADING}
  293. InitSystemThreads;
  294. {$endif FPC_HAS_FEATURE_THREADING}
  295. end.