si_prc.pp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2020 by Karoly Balogh
  4. System Entry point 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 si_prc;
  12. interface
  13. implementation
  14. {$i qdosfuncs.inc}
  15. var
  16. stacktop: pointer;
  17. setjmpbuf: jmp_buf;
  18. stklen: longint; external name '__stklen';
  19. binstart: byte; external name '_stext';
  20. binend: byte; external name '_etext';
  21. bssstart: byte; external name '_sbss';
  22. bssend: byte; external name '_ebss';
  23. { this is const, so it will go into the .data section, not .bss }
  24. const
  25. stackorig: pointer = nil;
  26. procedure PascalMain; external name 'PASCALMAIN';
  27. { this function must be the first in this unit which contains code }
  28. {$OPTIMIZATION OFF}
  29. function _FPC_proc_start: longint; cdecl; public name '_start';
  30. var
  31. newstack: pointer;
  32. begin
  33. _FPC_proc_start:=0;
  34. asm
  35. move.l d7,-(sp)
  36. { relocation code }
  37. { get our actual position in RAM }
  38. lea.l binstart(pc),a0
  39. move.l a0,d0
  40. { get an offset to the end of the binary. this works both
  41. relocated and not. The decision if to relocate is done
  42. later then }
  43. lea.l binend,a1
  44. lea.l binstart,a0
  45. sub.l a0,a1
  46. add.l d0,a1
  47. move.l d0,a0
  48. { read the relocation marker, this is always two padding bytes
  49. ad the end of .text, so we're free to poke there }
  50. move.w -2(a1),d7
  51. beq @noreloc
  52. { zero out the relocation marker, so if our code is called again
  53. without reload, it won't relocate itself twice }
  54. move.w #0,-2(a1)
  55. { first item in the relocation table is the number of relocs }
  56. move.l (a1)+,d7
  57. beq @noreloc
  58. @relocloop:
  59. { we read the offsets and relocate them }
  60. move.l (a1)+,d1
  61. add.l d0,(a0,d1)
  62. subq.l #1,d7
  63. bne @relocloop
  64. @noreloc:
  65. move.l (sp)+,d7
  66. { save the original stack pointer }
  67. move.l a7,stackorig
  68. end;
  69. { initialize .bss }
  70. FillChar(bssstart,PtrUInt(@bssend)-PtrUInt(@bssstart),#0);
  71. newstack:=mt_alchp(stklen,nil,-1);
  72. if not assigned(newstack) then
  73. _FPC_proc_start:=ERR_OM
  74. else
  75. begin
  76. stacktop:=pbyte(newstack)+stklen;
  77. asm
  78. move.l stacktop,sp
  79. end;
  80. if setjmp(setjmpbuf) = 0 then
  81. PascalMain;
  82. asm
  83. move.l stackorig,sp
  84. end;
  85. mt_rechp(newstack);
  86. end;
  87. end;
  88. procedure _FPC_proc_halt(_ExitCode: longint); public name '_haltproc';
  89. begin
  90. longjmp(setjmpbuf,1);
  91. end;
  92. end.