si_prc.pp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2016 by the Free Pascal development team
  4. System Entry point for Amiga/68k, Pascal only programs
  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 si_prc;
  12. interface
  13. implementation
  14. var
  15. AOS_ExecBase: Pointer; public name '_ExecBase';
  16. AOS_DosBase: Pointer; external name '_DOSBase';
  17. realExecBase: Pointer absolute $4;
  18. StkLen: LongInt; external name '__stklen';
  19. sysinit_jmpbuf: jmp_buf;
  20. ExitCode: LongInt;
  21. { the definitions in there need AOS_Execbase }
  22. {$include execd.inc}
  23. {$include execf.inc}
  24. {$include timerd.inc}
  25. {$include doslibd.inc}
  26. {$include doslibf.inc}
  27. {$if defined(AMIGA_V1_0_ONLY) or defined(AMIGA_V1_2_ONLY)}
  28. {$define AMIGA_LEGACY}
  29. {$include legacyexech.inc}
  30. {$endif}
  31. {$ifdef AMIGA_LEGACY}
  32. var
  33. args: pointer; public name '__fpc_args';
  34. arglen: dword; public name '__fpc_arglen';
  35. {$endif}
  36. var
  37. sst: TStackSwapStruct;
  38. const
  39. {$if defined(AMIGA_V1_0_ONLY)}
  40. NEEDS_NEWER_OS = 'This program needs newer OS.'+LineEnding;
  41. {$else}
  42. {$if defined(AMIGA_V1_2_ONLY)}
  43. NEEDS_NEWER_OS = 'This program needs OS 1.2 or newer.'+LineEnding;
  44. {$else}
  45. {$if defined(AMIGA_V2_0_ONLY)}
  46. NEEDS_NEWER_OS = 'This program needs OS 2.04 or newer.'+LineEnding;
  47. {$else}
  48. NEEDS_NEWER_OS = 'This program needs OS 3.0 or newer.'+LineEnding;
  49. {$endif}
  50. {$endif}
  51. {$endif}
  52. procedure PascalMain; external name 'PASCALMAIN';
  53. { this function must be the first in this unit which contains code }
  54. function _FPC_proc_start: longint; cdecl; public name '_start';
  55. var
  56. newStack: Pointer;
  57. task: PTask;
  58. begin
  59. {$IFDEF AMIGA_LEGACY}
  60. asm
  61. move.l d0, arglen
  62. move.l a0, args
  63. end;
  64. {$ENDIF}
  65. AOS_ExecBase:=realExecBase;
  66. if PLibrary(AOS_ExecBase)^.lib_Version < AMIGA_OS_MINVERSION then
  67. begin
  68. AOS_DOSBase:=OpenLibrary('dos.library',0);
  69. if AOS_DOSBase <> nil then
  70. begin
  71. dosWrite(dosOutput,PAnsiChar(NEEDS_NEWER_OS),length(NEEDS_NEWER_OS));
  72. CloseLibrary(AOS_DOSBase);
  73. end;
  74. exit(20);
  75. end;
  76. newStack:=nil;
  77. task:=FindTask(nil);
  78. if (task^.tc_SPUpper-task^.tc_SPLower < StkLen) then
  79. begin
  80. newStack:=AllocVec(StkLen,MEMF_ANY);
  81. sst.stk_Lower:=newStack;
  82. sst.stk_Upper:=newStack+StkLen;
  83. sst.stk_Pointer:=newStack+StkLen;
  84. StackSwap(@sst);
  85. end;
  86. { Note: code between the two stackswaps only works because of the
  87. nature of the generated code. We're accessing globals which is
  88. safe, and the locals are either kept in reg, or accessed via
  89. the base pointer (A5), and because we don't use the stack for
  90. call arguments, only regs. If this CG behavior changes, this
  91. code might break. In that case an asm-written StackSwap+call
  92. wrapper code is the solution. (Basically the reimplementation
  93. of AROS' NewStackSwap or MorphOS' NewPPCStackSwap.) (KB) }
  94. if setjmp(sysinit_jmpbuf) = 0 then
  95. PascalMain;
  96. if newStack <> nil then
  97. begin
  98. StackSwap(@sst);
  99. FreeVec(newStack);
  100. end;
  101. _FPC_proc_start:=ExitCode;
  102. end;
  103. procedure _FPC_proc_halt(_ExitCode: longint); cdecl; public name '_haltproc';
  104. begin
  105. ExitCode:=_ExitCode;
  106. longjmp(sysinit_jmpbuf,1);
  107. end;
  108. end.