system.pp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. unit system;
  2. {$ASMMODE intel}
  3. interface
  4. {$DEFINE FPC_INCLUDE_SOFTWARE_MUL}
  5. {$DEFINE FPC_INCLUDE_SOFTWARE_MOD_DIV}
  6. {$DEFINE FPC_USE_SMALL_DEFAULTSTACKSIZE}
  7. { To avoid warnings in thread.inc code,
  8. but value must be really given after
  9. systemh.inc is included otherwise the
  10. $mode switch is not effective }
  11. {$I systemh.inc}
  12. const
  13. LineEnding = #13#10;
  14. { LFNSupport is a variable here, defined below!!! }
  15. DirectorySeparator = '\';
  16. DriveSeparator = ':';
  17. ExtensionSeparator = '.';
  18. PathSeparator = ';';
  19. AllowDirectorySeparators : set of char = ['\','/'];
  20. AllowDriveSeparators : set of char = [':'];
  21. { FileNameCaseSensitive and FileNameCasePreserving are defined separately below!!! }
  22. maxExitCode = 255;
  23. MaxPathLen = 256;
  24. const
  25. { Default filehandles }
  26. UnusedHandle = $ffff;{ instead of -1, as it is a word value}
  27. StdInputHandle = 0;
  28. StdOutputHandle = 1;
  29. StdErrorHandle = 2;
  30. FileNameCaseSensitive : boolean = false;
  31. FileNameCasePreserving: boolean = false;
  32. CtrlZMarksEOF: boolean = true; (* #26 is considered as end of file *)
  33. sLineBreak = LineEnding;
  34. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  35. { Default memory segments (Tp7 compatibility) }
  36. seg0040 = $0040;
  37. segA000 = $A000;
  38. segB000 = $B000;
  39. segB800 = $B800;
  40. var
  41. { Mem[] support }
  42. mem : array[0..$7fff-1] of byte absolute $0:$0;
  43. memw : array[0..($7fff div sizeof(word))-1] of word absolute $0:$0;
  44. meml : array[0..($7fff div sizeof(longint))-1] of longint absolute $0:$0;
  45. { C-compatible arguments and environment }
  46. argc:longint; //!! public name 'operatingsystem_parameter_argc';
  47. argv:PPchar; //!! public name 'operatingsystem_parameter_argv';
  48. envp:PPchar; //!! public name 'operatingsystem_parameter_envp';
  49. dos_argv0 : pchar; //!! public name 'dos_argv0';
  50. dos_psp:Word;public name 'dos_psp';
  51. __stkbottom : pointer;public name '__stkbottom';
  52. __nearheap_start: pointer;public name '__nearheap_start';
  53. __nearheap_end: pointer;public name '__nearheap_end';
  54. AllFilesMask: string [3];
  55. {$ifndef RTLLITE}
  56. { System info }
  57. LFNSupport : boolean;
  58. {$ELSE RTLLITE}
  59. const
  60. LFNSupport = false;
  61. {$endif RTLLITE}
  62. procedure DebugWrite(const S: string);
  63. procedure DebugWriteLn(const S: string);
  64. implementation
  65. const
  66. fCarry = 1;
  67. var
  68. dos_version:Word;public name 'dos_version';
  69. {$I registers.inc}
  70. procedure Intr(IntNo: Byte; var Regs: Registers); external name 'FPC_INTR';
  71. procedure MsDos(var Regs: Registers); external name 'FPC_MSDOS';
  72. { invokes int 21h with the carry flag set on entry; used for the LFN functions
  73. to ensure that the carry flag is set on exit on older DOS versions which don't
  74. support them }
  75. procedure MsDos_Carry(var Regs: Registers); external name 'FPC_MSDOS_CARRY';
  76. {$I system.inc}
  77. {$I tinyheap.inc}
  78. procedure DebugWrite(const S: string);
  79. begin
  80. asm
  81. mov si, S
  82. lodsb
  83. mov cl, al
  84. xor ch, ch
  85. mov ah, 2
  86. @@1:
  87. lodsb
  88. mov dl, al
  89. int 21h
  90. loop @@1
  91. end ['ax','bx','cx','dx','si','di'];
  92. end;
  93. procedure DebugWriteLn(const S: string);
  94. begin
  95. DebugWrite(S);
  96. DebugWrite(#13#10);
  97. end;
  98. {*****************************************************************************
  99. ParamStr/Randomize
  100. *****************************************************************************}
  101. function GetProgramName: string;
  102. type
  103. PFarByte = ^Byte;far;
  104. PFarWord = ^Word;far;
  105. var
  106. dos_env_seg: Word;
  107. ofs: Word;
  108. Ch, Ch2: Char;
  109. begin
  110. if dos_version < $300 then
  111. begin
  112. GetProgramName := '';
  113. exit;
  114. end;
  115. dos_env_seg := PFarWord(Ptr(dos_psp, $2C))^;
  116. ofs := 1;
  117. repeat
  118. Ch := Chr(PFarByte(Ptr(dos_env_seg,ofs - 1))^);
  119. Ch2 := Chr(PFarByte(Ptr(dos_env_seg,ofs))^);
  120. if (Ch = #0) and (Ch2 = #0) then
  121. begin
  122. Inc(ofs, 3);
  123. GetProgramName := '';
  124. repeat
  125. Ch := Chr(PFarByte(Ptr(dos_env_seg,ofs))^);
  126. if Ch <> #0 then
  127. GetProgramName := GetProgramName + Ch;
  128. Inc(ofs);
  129. if ofs = 0 then
  130. begin
  131. GetProgramName := '';
  132. exit;
  133. end;
  134. until Ch = #0;
  135. exit;
  136. end;
  137. Inc(ofs);
  138. if ofs = 0 then
  139. begin
  140. GetProgramName := '';
  141. exit;
  142. end;
  143. until false;
  144. end;
  145. function paramcount : longint;
  146. begin
  147. paramcount := 0;
  148. end;
  149. function paramstr(l : longint) : string;
  150. begin
  151. if l = 0 then
  152. paramstr := GetProgramName
  153. else
  154. paramstr := '';
  155. end;
  156. procedure randomize;
  157. var
  158. hl : longint;
  159. regs : Registers;
  160. begin
  161. regs.AH:=$2C;
  162. MsDos(regs);
  163. hl:=regs.DX;
  164. randseed:=hl*$10000+ regs.CX;
  165. end;
  166. {*****************************************************************************
  167. System Dependent Exit code
  168. *****************************************************************************}
  169. procedure system_exit;
  170. var
  171. h : byte;
  172. begin
  173. for h:=0 to max_files-1 do
  174. if openfiles[h] then
  175. begin
  176. {$ifdef SYSTEMDEBUG}
  177. writeln(stderr,'file ',opennames[h],' not closed at exit');
  178. {$endif SYSTEMDEBUG}
  179. if h>=5 then
  180. do_close(h);
  181. end;
  182. asm
  183. mov al, byte [exitcode]
  184. mov ah, 4Ch
  185. int 21h
  186. end;
  187. end;
  188. {*****************************************************************************
  189. SystemUnit Initialization
  190. *****************************************************************************}
  191. procedure InitNearHeap;
  192. begin
  193. SetMemoryManager(TinyHeapMemoryManager);
  194. RegisterTinyHeapBlock(__nearheap_start, ptruint(__nearheap_end) - ptruint(__nearheap_start));
  195. end;
  196. function CheckLFN:boolean;
  197. var
  198. regs : Registers;
  199. RootName : pchar;
  200. buf : array [0..31] of char;
  201. begin
  202. { Check LFN API on drive c:\ }
  203. RootName:='C:\';
  204. { Call 'Get Volume Information' ($71A0) }
  205. regs.AX:=$71a0;
  206. regs.ES:=Seg(buf);
  207. regs.DI:=Ofs(buf);
  208. regs.CX:=32;
  209. regs.DS:=Seg(RootName^);
  210. regs.DX:=Ofs(RootName^);
  211. MsDos_Carry(regs);
  212. { If carryflag=0 and LFN API bit in ebx is set then use Long file names }
  213. CheckLFN:=(regs.Flags and fCarry=0) and (regs.BX and $4000=$4000);
  214. end;
  215. procedure SysInitStdIO;
  216. begin
  217. OpenStdIO(Input,fmInput,StdInputHandle);
  218. OpenStdIO(Output,fmOutput,StdOutputHandle);
  219. OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
  220. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  221. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  222. end;
  223. function GetProcessID: SizeUInt;
  224. begin
  225. GetProcessID := dos_psp;
  226. end;
  227. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  228. begin
  229. result := stklen;
  230. end;
  231. begin
  232. StackLength := CheckInitialStkLen(InitialStkLen);
  233. StackBottom := __stkbottom;
  234. if DetectFPU then
  235. SysInitFPU;
  236. { To be set if this is a GUI or console application }
  237. IsConsole := TRUE;
  238. { To be set if this is a library and not a program }
  239. IsLibrary := FALSE;
  240. { Setup heap }
  241. InitNearHeap;
  242. SysInitExceptions;
  243. initunicodestringmanager;
  244. { Setup stdin, stdout and stderr }
  245. SysInitStdIO;
  246. { Use LFNSupport LFN }
  247. LFNSupport:=CheckLFN;
  248. if LFNSupport then
  249. begin
  250. FileNameCasePreserving:=true;
  251. AllFilesMask := '*';
  252. end
  253. else
  254. AllFilesMask := '*.*';
  255. { Reset IO Error }
  256. InOutRes:=0;
  257. initvariantmanager;
  258. end.