mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 04:39:28 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			124 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    This file is part of the Free Pascal run time library.
 | 
						|
    Copyright (c) 2017 by the Free Pascal development team
 | 
						|
 | 
						|
    System Entry point for PalmOS, Pascal only programs
 | 
						|
 | 
						|
    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.
 | 
						|
 | 
						|
 **********************************************************************}
 | 
						|
{$SMARTLINK OFF}
 | 
						|
unit si_prc;
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
{$i palmos.inc}
 | 
						|
 | 
						|
var
 | 
						|
  appInfo: SysAppInfoPtr; public name '__appInfo';
 | 
						|
  StkLen: LongInt; external name '__stklen';
 | 
						|
  sysinit_jmpbuf: jmp_buf;
 | 
						|
  ExitCode: LongInt;
 | 
						|
 | 
						|
var
 | 
						|
  { this is declared by the PalmOS linker script }
 | 
						|
  data_start: pbyte; external name 'data_start';
 | 
						|
 | 
						|
 | 
						|
procedure PascalMain; external name 'PASCALMAIN';
 | 
						|
procedure FPCRelocateData; forward;
 | 
						|
 | 
						|
{ this function must be the first in this unit which contains code }
 | 
						|
function _FPC_proc_start: longint; cdecl; public name '_start';
 | 
						|
var
 | 
						|
  locAppInfo: SysAppInfoPtr;
 | 
						|
  prevGlobals: Pointer;
 | 
						|
  globalsPtr: Pointer;
 | 
						|
begin
 | 
						|
  _FPC_proc_start:=0;
 | 
						|
 | 
						|
  if SysAppStartup(locAppInfo, prevGlobals, globalsPtr) <> 0 then
 | 
						|
    begin
 | 
						|
      SndPlaySystemSound(sndError);
 | 
						|
      exit(-1);
 | 
						|
    end;
 | 
						|
 | 
						|
  if (locAppInfo^.launchFlags and sysAppLaunchFlagNewGlobals) > 0 then
 | 
						|
    FPCRelocateData;
 | 
						|
 | 
						|
  { we don't support anything but normal startup now }
 | 
						|
  { FIXME: figure it out how various startup commands can }
 | 
						|
  { coexist with the normal system unit infrastructure (KB) }
 | 
						|
  if locAppInfo^.cmd = sysAppLaunchCmdNormalLaunch then
 | 
						|
    begin
 | 
						|
      if setjmp(sysinit_jmpbuf) = 0 then
 | 
						|
        begin
 | 
						|
          appInfo:=locAppInfo;
 | 
						|
          PascalMain;
 | 
						|
        end;
 | 
						|
      _FPC_proc_start:=ExitCode;
 | 
						|
    end;
 | 
						|
 | 
						|
  SysAppExit(locAppInfo, prevGlobals, globalsPtr);
 | 
						|
end;
 | 
						|
 | 
						|
procedure _FPC_proc_halt(_ExitCode: longint); cdecl; public name '_haltproc';
 | 
						|
begin
 | 
						|
  ExitCode:=_ExitCode;
 | 
						|
  longjmp(sysinit_jmpbuf,1);
 | 
						|
end;
 | 
						|
 | 
						|
{ data segment relocation magic, ported to Pascal from prc-tools C version }
 | 
						|
type
 | 
						|
  PReloc = ^TReloc;
 | 
						|
  TReloc = record
 | 
						|
    case boolean of
 | 
						|
      true: ( next: smallint; addend: word );
 | 
						|
      false: ( value: dword );
 | 
						|
  end;
 | 
						|
 | 
						|
procedure RelocateChain(offset: smallint; base: pointer);
 | 
						|
var
 | 
						|
  data_res: pbyte;
 | 
						|
  site: PReloc;
 | 
						|
begin
 | 
						|
  data_res:=@data_start;
 | 
						|
 | 
						|
  while offset >= 0 do
 | 
						|
    begin
 | 
						|
      site:=PReloc(data_res + offset);
 | 
						|
      offset:=site^.next;
 | 
						|
      site^.next:=0;
 | 
						|
      site^.value:=site^.value + PtrUInt(base);
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure FPCRelocateData;
 | 
						|
var
 | 
						|
  relocH: MemHandle;
 | 
						|
  chain: psmallint;
 | 
						|
const
 | 
						|
  rloc_id = $726c6f63; // 'rloc'
 | 
						|
begin
 | 
						|
  relocH:=DmGet1Resource(rloc_id, 0);
 | 
						|
  if relocH <> nil then
 | 
						|
    begin
 | 
						|
      chain:=MemHandleLock(relocH);
 | 
						|
      RelocateChain(chain^, @data_start);
 | 
						|
      Inc(chain);
 | 
						|
      RelocateChain(chain^, @_FPC_proc_start);
 | 
						|
      Inc(chain);
 | 
						|
      MemHandleUnlock(relocH);
 | 
						|
      DmReleaseResource(relocH);
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
end.
 |