Browse Source

+ RTL part of WinCE patches from Yuri Sidorov

git-svn-id: trunk@572 -
florian 20 years ago
parent
commit
8adc1c9b0c
11 changed files with 1531 additions and 58 deletions
  1. 3 0
      .gitattributes
  2. 2 0
      rtl/arm/arm.inc
  3. 10 0
      rtl/win/sysdir.inc
  4. 4 0
      rtl/win/sysfile.inc
  5. 3 3
      rtl/win/sysheap.inc
  6. 33 25
      rtl/win/sysos.inc
  7. 9 0
      rtl/win/sysosh.inc
  8. 33 30
      rtl/win/systhrd.inc
  9. 241 0
      rtl/wince/Makefile.fpc
  10. 1126 0
      rtl/wince/system.pp
  11. 67 0
      rtl/wince/wprt0.as

+ 3 - 0
.gitattributes

@@ -4176,6 +4176,9 @@ rtl/win32/wprt0_10.as -text
 rtl/win64/Makefile svneol=native#text/plain
 rtl/win64/Makefile.fpc svneol=native#text/plain
 rtl/win64/system.pp svneol=native#text/plain
+rtl/wince/Makefile.fpc svneol=native#text/plain
+rtl/wince/system.pp svneol=native#text/plain
+rtl/wince/wprt0.as svneol=native#text/plain
 rtl/x86_64/int64p.inc svneol=native#text/plain
 rtl/x86_64/makefile.cpu -text
 rtl/x86_64/math.inc svneol=native#text/plain

+ 2 - 0
rtl/arm/arm.inc

@@ -19,12 +19,14 @@
 
 procedure fpc_cpuinit;
 begin
+{$IFNDEF WINCE}
   asm
     rfs r0
     and r0,r0,#0xffe0ffff
     orr r0,r0,#0x00020000
     wfs r0
   end;
+{$ENDIF}
 end;
 
 {****************************************************************************

+ 10 - 0
rtl/win/sysdir.inc

@@ -58,20 +58,27 @@ end;
 
 procedure chdir(const s:string);[IOCHECK];
 begin
+{$ifndef WINCE}
   If (s='') or (InOutRes <> 0) then
    exit;
   dirfn(TDirFnType(@SetCurrentDirectory),s);
   if Inoutres=2 then
    Inoutres:=3;
+{$else WINCE}
+  InOutRes:=1;
+{$endif WINCE}
 end;
 
 procedure GetDir (DriveNr: byte; var Dir: ShortString);
+{$ifndef WINCE}
 const
   Drive:array[0..3]of char=(#0,':',#0,#0);
+{$endif WINCE}
 var
   defaultdrive:boolean;
   DirBuf,SaveBuf:array[0..259] of Char;
 begin
+{$ifndef WINCE}
   defaultdrive:=drivenr=0;
   if not defaultdrive then
    begin
@@ -92,6 +99,9 @@ begin
   dir:=strpas(DirBuf);
   if not FileNameCaseSensitive then
    dir:=upcase(dir);
+{$else WINCE}
+  Dir:='\';
+{$endif WINCE}
 end;
 
 {

+ 4 - 0
rtl/win/sysfile.inc

@@ -29,7 +29,11 @@ end;
 
 function do_isdevice(handle:thandle):boolean;
 begin
+{$ifndef WINCE}
   do_isdevice:=(getfiletype(handle)=2);
+{$else WINCE}
+  do_isdevice:=False;
+{$endif WINCE}
 end;
 
 

+ 3 - 3
rtl/win/sysheap.inc

@@ -20,11 +20,11 @@
 
    { memory functions }
    function GetProcessHeap : THandle;
-     stdcall;external 'kernel32' name 'GetProcessHeap';
+     stdcall;external KernelDLL name 'GetProcessHeap';
    function HeapAlloc(hHeap : DWord; dwFlags : DWord; dwBytes : SIZE_T) : pointer;
-     stdcall;external 'kernel32' name 'HeapAlloc';
+     stdcall;external KernelDLL name 'HeapAlloc';
    function HeapFree(hHeap : THandle; dwFlags : dword; lpMem: pointer) : boolean;
-     stdcall;external 'kernel32' name 'HeapFree';
+     stdcall;external KernelDLL name 'HeapFree';
 {$IFDEF SYSTEMDEBUG}
    function WinAPIHeapSize(hHeap : THandle; dwFlags : DWord; ptr : Pointer) : DWord;
      stdcall;external 'kernel32' name 'HeapSize';

+ 33 - 25
rtl/win/sysos.inc

@@ -171,76 +171,84 @@ threadvar
 
    { misc. functions }
    function GetLastError : DWORD;
-     stdcall;external 'kernel32' name 'GetLastError';
+     stdcall;external KernelDLL name 'GetLastError';
 
    { time and date functions }
    function GetTickCount : longint;
-     stdcall;external 'kernel32' name 'GetTickCount';
+     stdcall;external KernelDLL name 'GetTickCount';
 
+{$ifndef WINCE}
    { process functions }
    procedure ExitProcess(uExitCode : UINT);
-     stdcall;external 'kernel32' name 'ExitProcess';
+     stdcall;external KernelDLL name 'ExitProcess';
 
    { Startup }
    procedure GetStartupInfo(p : pointer);
-     stdcall;external 'kernel32' name 'GetStartupInfoA';
+     stdcall;external KernelDLL name 'GetStartupInfoA';
    function GetStdHandle(nStdHandle:DWORD):THANDLE;
-     stdcall;external 'kernel32' name 'GetStdHandle';
+     stdcall;external KernelDLL name 'GetStdHandle';
+{$endif WINCE}
 
    { command line/enviroment functions }
    function GetCommandLine : pchar;
-     stdcall;external 'kernel32' name 'GetCommandLineA';
+     stdcall;external KernelDLL name 'GetCommandLine' + ApiSuffix;
 
+{$ifndef WINCE}
   function GetCurrentProcessId:DWORD;
-    stdcall; external 'kernel32' name 'GetCurrentProcessId';
+    stdcall; external KernelDLL name 'GetCurrentProcessId';
 
   function Win32GetCurrentThreadId:DWORD;
-    stdcall; external 'kernel32' name 'GetCurrentThreadId';
+    stdcall; external KernelDLL name 'GetCurrentThreadId';
+{$endif WINCE}
 
    { module functions }
    function GetModuleFileName(l1:longint;p:pointer;l2:longint):longint;
-     stdcall;external 'kernel32' name 'GetModuleFileNameA';
+     stdcall;external KernelDLL name 'GetModuleFileName' + ApiSuffix;
    function GetModuleHandle(p : pointer) : longint;
-     stdcall;external 'kernel32' name 'GetModuleHandleA';
+     stdcall;external KernelDLL name 'GetModuleHandle' + ApiSuffix;
    function GetCommandFile:pchar;forward;
 
    { file functions }
    function WriteFile(fh:thandle;buf:pointer;len:longint;var loaded:longint;
      overlap:pointer):longint;
-     stdcall;external 'kernel32' name 'WriteFile';
+     stdcall;external KernelDLL name 'WriteFile';
    function ReadFile(fh:thandle;buf:pointer;len:longint;var loaded:longint;
      overlap:pointer):longint;
-     stdcall;external 'kernel32' name 'ReadFile';
+     stdcall;external KernelDLL name 'ReadFile';
    function CloseHandle(h : thandle) : longint;
-     stdcall;external 'kernel32' name 'CloseHandle';
+     stdcall;external KernelDLL name 'CloseHandle';
    function DeleteFile(p : pchar) : longint;
-     stdcall;external 'kernel32' name 'DeleteFileA';
+     stdcall;external KernelDLL name 'DeleteFile' + ApiSuffix;
    function MoveFile(old,_new : pchar) : longint;
-     stdcall;external 'kernel32' name 'MoveFileA';
+     stdcall;external KernelDLL name 'MoveFile' + ApiSuffix;
    function SetFilePointer(l1,l2 : thandle;l3 : pointer;l4 : longint) : longint;
-     stdcall;external 'kernel32' name 'SetFilePointer';
+     stdcall;external KernelDLL name 'SetFilePointer';
    function GetFileSize(h:thandle;p:pointer) : longint;
-     stdcall;external 'kernel32' name 'GetFileSize';
+     stdcall;external KernelDLL name 'GetFileSize';
    function CreateFile(lpFileName:pchar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
                        lpSecurityAttributes:PSECURITYATTRIBUTES; dwCreationDisposition:DWORD;
                        dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):longint;
-     stdcall;external 'kernel32' name 'CreateFileA';
+     stdcall;external KernelDLL name 'CreateFile' + ApiSuffix;
    function SetEndOfFile(h : thandle) : longbool;
-     stdcall;external 'kernel32' name 'SetEndOfFile';
+     stdcall;external KernelDLL name 'SetEndOfFile';
+{$ifndef WINCE}
    function GetFileType(Handle:thandle):DWord;
-     stdcall;external 'kernel32' name 'GetFileType';
+     stdcall;external KernelDLL name 'GetFileType';
+{$endif WINCE}
    function GetFileAttributes(p : pchar) : dword;
-     stdcall;external 'kernel32' name 'GetFileAttributesA';
+     stdcall;external KernelDLL name 'GetFileAttributes' + ApiSuffix;
 
    { Directory }
    function CreateDirectory(name : pointer;sec : pointer) : longbool;
-     stdcall;external 'kernel32' name 'CreateDirectoryA';
+     stdcall;external KernelDLL name 'CreateDirectory' + ApiSuffix;
    function RemoveDirectory(name:pointer):longbool;
-     stdcall;external 'kernel32' name 'RemoveDirectoryA';
+     stdcall;external KernelDLL name 'RemoveDirectory' + ApiSuffix;
+{$ifndef WINCE}
    function SetCurrentDirectory(name : pointer) : longbool;
-     stdcall;external 'kernel32' name 'SetCurrentDirectoryA';
+     stdcall;external KernelDLL name 'SetCurrentDirectory' + ApiSuffix;
    function GetCurrentDirectory(bufsize : longint;name : pchar) : longbool;
-     stdcall;external 'kernel32' name 'GetCurrentDirectoryA';
+     stdcall;external KernelDLL name 'GetCurrentDirectory' + ApiSuffix;
+{$endif WINCE}
 
    Procedure Errno2InOutRes;
    Begin

+ 9 - 0
rtl/win/sysosh.inc

@@ -37,3 +37,12 @@ type
     LockSemaphore : THandle;
     SpinCount : ULONG_PTR;
   end;
+
+const
+{$ifdef WINCE}
+  KernelDLL = 'coredll';
+  ApiSuffix = 'W';
+{$else WINCE}
+  KernelDLL = 'kernel32';
+  ApiSuffix = 'A';
+{$endif WINCE}

+ 33 - 30
rtl/win/systhrd.inc

@@ -20,38 +20,41 @@
 *****************************************************************************}
 
 const
-  { GlobalAlloc, GlobalFlags  }
-  GMEM_FIXED = 0;
-  GMEM_ZEROINIT = 64;
+  { LocalAlloc flags  }
+  LMEM_FIXED = 0;
+  LMEM_ZEROINIT = 64;
 
+{$ifndef WINCE}
 function TlsAlloc : DWord;
-  stdcall;external 'kernel32' name 'TlsAlloc';
+  stdcall;external KernelDLL name 'TlsAlloc';
+function TlsFree(dwTlsIndex : DWord) : LongBool;
+  stdcall;external KernelDLL name 'TlsFree';
+{$endif WINCE}
 function TlsGetValue(dwTlsIndex : DWord) : pointer;
-  stdcall;external 'kernel32' name 'TlsGetValue';
+  stdcall;external KernelDLL name 'TlsGetValue';
 function TlsSetValue(dwTlsIndex : DWord;lpTlsValue : pointer) : LongBool;
-  stdcall;external 'kernel32' name 'TlsSetValue';
-function TlsFree(dwTlsIndex : DWord) : LongBool;
-  stdcall;external 'kernel32' name 'TlsFree';
+  stdcall;external KernelDLL name 'TlsSetValue';
 function CreateThread(lpThreadAttributes : pointer;
   dwStackSize : SIZE_T; lpStartAddress : pointer;lpParameter : pointer;
   dwCreationFlags : DWord;var lpThreadId : DWord) : THandle;
-  stdcall;external 'kernel32' name 'CreateThread';
+  stdcall;external KernelDLL name 'CreateThread';
 procedure ExitThread(dwExitCode : DWord);
-  stdcall;external 'kernel32' name 'ExitThread';
-function GlobalAlloc(uFlags:DWord; dwBytes:DWORD):Pointer;
-  stdcall;external 'kernel32' name 'GlobalAlloc';
-function GlobalFree(hMem : Pointer):Pointer; stdcall;external 'kernel32' name 'GlobalFree';
-procedure Sleep(dwMilliseconds: DWord); stdcall;external 'kernel32' name 'Sleep';
-function  WinSuspendThread (threadHandle : THandle) : dword; stdcall;external 'kernel32' name 'SuspendThread';
-function  WinResumeThread  (threadHandle : THandle) : dword; stdcall;external 'kernel32' name 'ResumeThread';
-function  TerminateThread  (threadHandle : THandle; var exitCode : dword) : boolean; stdcall;external 'kernel32' name 'TerminateThread';
-function  WaitForSingleObject (hHandle : THandle;Milliseconds: dword): dword; stdcall;external 'kernel32' name 'WaitForSingleObject';
-function  WinThreadSetPriority (threadHandle : THandle; Prio: longint): boolean; stdcall;external 'kernel32' name 'SetThreadPriority';
-function  WinThreadGetPriority (threadHandle : THandle): LongInt; stdcall;external 'kernel32' name 'GetThreadPriority';
-function  WinGetCurrentThreadId : dword; stdcall;external 'kernel32' name 'GetCurrentThread';
-function  CreateEvent(lpEventAttributes:pointer;bManualReset:longbool;bInitialState:longbool;lpName:pchar): THandle; stdcall; external 'kernel32' name 'CreateEventA';
-function  ResetEvent(hEvent:THandle):LONGBOOL; stdcall; external 'kernel32' name 'ResetEvent';
-function  SetEvent(hEvent:THandle):LONGBOOL; stdcall; external 'kernel32' name 'SetEvent';
+  stdcall;external KernelDLL name 'ExitThread';
+function LocalAlloc(uFlags:DWord; dwBytes:DWORD):Pointer;
+  stdcall;external KernelDLL name 'LocalAlloc';
+function LocalFree(hMem : Pointer):Pointer; stdcall;external KernelDLL name 'LocalFree';
+procedure Sleep(dwMilliseconds: DWord); stdcall;external KernelDLL name 'Sleep';
+function  WinSuspendThread (threadHandle : THandle) : dword; stdcall;external KernelDLL name 'SuspendThread';
+function  WinResumeThread  (threadHandle : THandle) : dword; stdcall;external KernelDLL name 'ResumeThread';
+function  TerminateThread  (threadHandle : THandle; var exitCode : dword) : boolean; stdcall;external KernelDLL name 'TerminateThread';
+function  WaitForSingleObject (hHandle : THandle;Milliseconds: dword): dword; stdcall;external KernelDLL name 'WaitForSingleObject';
+function  WinThreadSetPriority (threadHandle : THandle; Prio: longint): boolean; stdcall;external KernelDLL name 'SetThreadPriority';
+function  WinThreadGetPriority (threadHandle : THandle): LongInt; stdcall;external KernelDLL name 'GetThreadPriority';
+function  CreateEvent(lpEventAttributes:pointer;bManualReset:longbool;bInitialState:longbool;lpName:pchar): THandle; stdcall; external KernelDLL name 'CreateEvent' + ApiSuffix;
+{$ifndef WINCE}
+function  ResetEvent(hEvent:THandle):LONGBOOL; stdcall; external KernelDLL name 'ResetEvent';
+function  SetEvent(hEvent:THandle):LONGBOOL; stdcall; external KernelDLL name 'SetEvent';
+{$endif WINCE}
 
 CONST
    WAIT_OBJECT_0 = 0;
@@ -94,14 +97,14 @@ CONST
         { exceptions which use threadvars but       }
         { these aren't allocated yet ...            }
         { allocate room on the heap for the thread vars }
-        dataindex:=pointer(GlobalAlloc(GMEM_FIXED or GMEM_ZEROINIT,threadvarblocksize));
+        dataindex:=pointer(LocalAlloc(LMEM_FIXED or LMEM_ZEROINIT,threadvarblocksize));
         TlsSetValue(tlskey,dataindex);
       end;
 
 
     procedure SysReleaseThreadVars;
       begin
-        GlobalFree(TlsGetValue(tlskey));
+        LocalFree(TlsGetValue(tlskey));
       end;
 
 
@@ -244,16 +247,16 @@ CONST
 *****************************************************************************}
 
 procedure WinInitCriticalSection(var cs : TRTLCriticalSection);
-  stdcall;external 'kernel32' name 'InitializeCriticalSection';
+  stdcall;external KernelDLL name 'InitializeCriticalSection';
 
 procedure WinDoneCriticalSection(var cs : TRTLCriticalSection);
-  stdcall;external 'kernel32' name 'DeleteCriticalSection';
+  stdcall;external KernelDLL name 'DeleteCriticalSection';
 
 procedure WinEnterCriticalSection(var cs : TRTLCriticalSection);
-  stdcall;external 'kernel32' name 'EnterCriticalSection';
+  stdcall;external KernelDLL name 'EnterCriticalSection';
 
 procedure WinLeaveCriticalSection(var cs : TRTLCriticalSection);
-  stdcall;external 'kernel32' name 'LeaveCriticalSection';
+  stdcall;external KernelDLL name 'LeaveCriticalSection';
 
 procedure SySInitCriticalSection(var cs);
 begin

+ 241 - 0
rtl/wince/Makefile.fpc

@@ -0,0 +1,241 @@
+#
+#   Makefile.fpc for Free Pascal WinCE RTL
+#
+
+[package]
+main=rtl
+
+[target]
+loaders= wprt0 #wdllprt0 gprt0 wcygprt0
+units=$(SYSTEMUNIT) objpas # ctypes objpas macpas strings \
+#     lineinfo heaptrc matrix \
+#     windows winsock initc cmem dynlibs signals \
+#     dos crt objects graph messages \
+#     rtlconsts sysconst sysutils math types \
+#     strutils convutils dateutils varutils variants typinfo classes \
+#     cpu mmx charset ucomplex getopts \
+#     wincrt winmouse winevent sockets printer \
+#     video mouse keyboard \
+#     winsysut
+
+rsts=math varutils typinfo variants classes dateutils sysconst
+
+[require]
+nortl=y
+
+[install]
+fpcpackage=y
+
+[default]
+fpcdir=../..
+target=wince
+
+[compiler]
+includedir=$(INC) $(PROCINC) $(RTL)/win
+sourcedir=$(INC) $(PROCINC)
+
+
+[prerules]
+RTL=..
+INC=$(RTL)/inc
+PROCINC=$(RTL)/$(CPU_TARGET)
+#WININC=wininc
+
+UNITPREFIX=rtl
+
+SYSTEMUNIT=system
+PRT0=wprt0
+
+# Use new feature from 1.0.5 version
+# that generates release PPU files
+# which will not be recompiled
+ifdef RELEASE
+override FPCOPT+=-Ur
+endif
+
+# Paths
+OBJPASDIR=$(RTL)/objpas
+GRAPHDIR=$(INC)/graph
+
+# Files used by windows.pp
+# include $(WININC)/makefile.inc
+
+#WINDOWS_SOURCE_FILES=$(addprefix $(WININC)/,$(addsuffix .inc,$(WINDOWS_FILES)))
+
+
+[rules]
+SYSTEMPPU=$(addsuffix $(PPUEXT),$(SYSTEMUNIT))
+
+# Get the system independent include file names.
+# This will set the following variables :
+# SYSINCNAMES
+include $(INC)/makefile.inc
+SYSINCDEPS=$(addprefix $(INC)/,$(SYSINCNAMES))
+
+# Get the processor dependent include file names.
+# This will set the following variables :
+# CPUINCNAMES
+include $(PROCINC)/makefile.cpu
+SYSCPUDEPS=$(addprefix $(PROCINC)/,$(CPUINCNAMES))
+
+# Put system unit dependencies together.
+SYSDEPS=$(SYSINCDEPS) $(SYSCPUDEPS)
+
+
+#
+# Loaders
+#
+
+wprt0$(OEXT) : $(PRT0).as
+        $(AS) -o $(UNITTARGETDIRPREFIX)wprt0$(OEXT) $(PRT0).as
+
+gprt0$(OEXT) : gprt0.as
+
+wdllprt0$(OEXT) : wdllprt0.as
+
+wcygprt0$(OEXT) : wcygprt0.as
+
+#
+# System Units (System, Objpas, Strings)
+#
+
+$(SYSTEMUNIT)$(PPUEXT) : $(SYSTEMUNIT).pp $(SYSDEPS)
+        $(COMPILER) -Us -Sg $(SYSTEMUNIT).pp #-Fi..\win
+
+objpas$(PPUEXT): $(OBJPASDIR)/objpas.pp $(INC)/except.inc $(SYSTEMUNIT)$(PPUEXT)
+        $(COMPILER) -I$(OBJPASDIR) $(OBJPASDIR)/objpas.pp
+
+strings$(PPUEXT) : $(INC)/strings.pp $(INC)/stringsi.inc\
+                   $(PROCINC)/strings.inc $(PROCINC)/stringss.inc\
+                   $(SYSTEMUNIT)$(PPUEXT)
+
+#
+# System Dependent Units
+#
+
+#windows$(PPUEXT) : windows.pp $(WINDOWS_SOURCE_FILES) $(SYSTEMUNIT)$(PPUEXT)
+#        $(COMPILER) -I$(WININC) windows.pp
+
+#messages$(PPUEXT): messages.pp $(WININC)/messages.inc $(SYSTEMUNIT)$(PPUEXT)
+#        $(COMPILER) -I$(WININC) messages.pp
+
+#opengl32$(PPUEXT) : opengl32.pp windows$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT)
+
+#winsock$(PPUEXT) : winsock.pp windows$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT)
+
+#sockets$(PPUEXT) : sockets.pp windows$(PPUEXT) winsock$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT) \
+#                   $(INC)/sockets.inc $(INC)/socketsh.inc
+
+#initc$(PPUEXT) : initc.pp $(SYSTEMUNIT)$(PPUEXT)
+
+#wincrt$(PPUEXT) : wincrt.pp $(SYSTEMUNIT)$(PPUEXT) windows$(PPUEXT) graph$(PPUEXT)
+
+#winmouse$(PPUEXT) : winmouse.pp $(SYSTEMUNIT)$(PPUEXT) windows$(PPUEXT) graph$(PPUEXT)
+
+#dynlibs$(PPUEXT) : $(INC)/dynlibs.pp windows$(PPUEXT)
+
+#
+# TP7 Compatible RTL Units
+#
+
+#dos$(PPUEXT) : dos.pp $(INC)/filerec.inc $(INC)/textrec.inc strings$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT)
+
+#crt$(PPUEXT) : crt.pp $(INC)/textrec.inc $(SYSTEMUNIT)$(PPUEXT) objpas$(PPUEXT) dos$(PPUEXT) windows$(PPUEXT)
+
+#objects$(PPUEXT) : $(INC)/objects.pp $(SYSTEMUNIT)$(PPUEXT)
+
+#
+# Graph
+#
+
+#include $(GRAPHDIR)/makefile.inc
+#GRAPHINCDEPS=$(addprefix $(GRAPHDIR)/,$(GRAPHINCNAMES))
+
+#graph$(PPUEXT) : graph.pp strings$(PPUEXT) windows$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT) \
+#                 $(GRAPHINCDEPS)
+#        $(COMPILER) -I$(GRAPHDIR) graph.pp
+
+
+#
+# Delphi Compatible Units
+#
+
+#sysutils$(PPUEXT) : sysutils.pp $(wildcard $(OBJPASDIR)/sysutils/*.inc) \
+#                    objpas$(PPUEXT) dos$(PPUEXT) windows$(PPUEXT) sysconst$(PPUEXT)
+#        $(COMPILER) -Fi$(OBJPASDIR)/sysutils sysutils.pp
+
+#classes$(PPUEXT) : classes.pp $(wildcard $(OBJPASDIR)/classes/*.inc) \
+#                   sysutils$(PPUEXT) typinfo$(PPUEXT) rtlconsts$(PPUEXT) sysconst$(PPUEXT)
+#        $(COMPILER) -Fi$(OBJPASDIR)/classes classes.pp
+
+#winsysut$(PPUEXT) : winsysut.pp sysutils$(PPUEXT)
+#        $(COMPILER) winsysut.pp
+
+#typinfo$(PPUEXT): $(OBJPASDIR)/typinfo.pp objpas$(PPUEXT)
+#        $(COMPILER) -Sg $(OBJPASDIR)/typinfo.pp
+
+#math$(PPUEXT): $(OBJPASDIR)/math.pp objpas$(PPUEXT) sysutils$(PPUEXT)
+#        $(COMPILER) $(OBJPASDIR)/math.pp
+
+#varutils$(PPUEXT) : $(OBJPASDIR)/cvarutil.inc $(OBJPASDIR)/varutils.inc \
+#                    $(OBJPASDIR)/varutilh.inc varutils.pp sysutils$(PPUEXT)
+#        $(COMPILER) -Fi$(OBJPASDIR) varutils.pp
+
+#variants$(PPUEXT) : $(INC)/variants.pp varutils$(PPUEXT) sysutils$(PPUEXT) sysconst$(PPUEXT) typinfo$(PPUEXT) rtlconsts$(PPUEXT)
+#        $(COMPILER) -Fi$(INC) $(INC)/variants.pp
+
+#types$(PPUEXT) : $(OBJPASDIR)/types.pp objpas$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT)
+#        $(COMPILER) $(OBJPASDIR)/types.pp
+
+#rtlconsts$(PPUEXT) : objpas$(PPUEXT) $(OBJPASDIR)/rtlconsts.pp
+#        $(COMPILER) $(OBJPASDIR)/rtlconsts.pp
+
+#sysconst$(PPUEXT) : $(OBJPASDIR)/sysconst.pp objpas$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT)
+#        $(COMPILER) $(OBJPASDIR)/sysconst.pp
+
+#dateutils$(PPUEXT) : $(OBJPASDIR)/dateutils.pp
+#        $(COMPILER) -I$(OBJPASDIR) $(OBJPASDIR)/dateutils.pp
+
+#convutils$(PPUEXT) : $(OBJPASDIR)/convutils.pp
+#        $(COMPILER) -I$(OBJPASDIR) $(OBJPASDIR)/convutils.pp
+
+#strutils$(PPUEXT) : $(OBJPASDIR)/strutils.pp
+#        $(COMPILER) -I$(OBJPASDIR) $(OBJPASDIR)/strutils.pp
+
+#
+# Mac Pascal Model
+#
+
+#macpas$(PPUEXT) : $(INC)/macpas.pp $(SYSTEMUNIT)$(PPUEXT)
+#        $(COMPILER) $(INC)/macpas.pp $(REDIR)
+
+#
+# Other system-independent RTL Units
+#
+
+cpu$(PPUEXT) : $(PROCINC)/cpu.pp $(SYSTEMUNIT)$(PPUEXT)
+
+mmx$(PPUEXT) : $(PROCINC)/mmx.pp cpu$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT)
+
+getopts$(PPUEXT) : $(INC)/getopts.pp $(SYSTEMUNIT)$(PPUEXT)
+
+heaptrc$(PPUEXT) : $(INC)/heaptrc.pp $(SYSTEMUNIT)$(PPUEXT)
+        $(COMPILER) -Sg $(INC)/heaptrc.pp
+
+lineinfo$(PPUEXT) : $(INC)/lineinfo.pp $(SYSTEMUNIT)$(PPUEXT)
+
+charset$(PPUEXT) : $(INC)/charset.pp $(SYSTEMUNIT)$(PPUEXT)
+
+cmem$(PPUEXT) : $(INC)/cmem.pp $(SYSTEMUNIT)$(PPUEXT)
+
+ucomplex$(PPUEXT) : $(INC)/ucomplex.pp math$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT)
+
+#
+# Other system-dependent RTL Units
+#
+
+#callspec$(PPUEXT) : $(INC)/callspec.pp $(SYSTEMUNIT)$(PPUEXT)
+
+#ctypes$(PPUEXT) :  $(INC)/ctypes.pp $(SYSTEMUNIT)$(PPUEXT)
+
+#variants$(PPUEXT) : $(INC)/variants.pp varutils$(PPUEXT) typinfo$(PPUEXT)

+ 1126 - 0
rtl/wince/system.pp

@@ -0,0 +1,1126 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2005 by Florian Klaempfl and Pavel Ozerski
+    and Yury Sidorov member of the Free Pascal development team.
+
+    FPC Pascal system unit for the WinCE.
+
+    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.
+
+ **********************************************************************}
+unit System;
+interface
+
+{$ifdef SYSTEMDEBUG}
+  {$define SYSTEMEXCEPTIONDEBUG}
+{$endif SYSTEMDEBUG}
+
+{$ifdef cpui386}
+  {$define Set_i386_Exception_handler}
+{$endif cpui386}
+
+{ include system-independent routine headers }
+{$I systemh.inc}
+
+const
+ LineEnding = #13#10;
+ LFNSupport = true;
+ DirectorySeparator = '\';
+ DriveSeparator = ':';
+ PathSeparator = ';';
+{ FileNameCaseSensitive is defined separately below!!! }
+ maxExitCode = 65535;
+ MaxPathLen = 260;
+
+type
+   PEXCEPTION_FRAME = ^TEXCEPTION_FRAME;
+   TEXCEPTION_FRAME = record
+     next : PEXCEPTION_FRAME;
+     handler : pointer;
+   end;
+
+const
+{ Default filehandles }
+  UnusedHandle    : THandle = -1;
+  StdInputHandle  : THandle = 0;
+  StdOutputHandle : THandle = 0;
+  StdErrorHandle  : THandle = 0;
+
+  FileNameCaseSensitive : boolean = true;
+  CtrlZMarksEOF: boolean = true; (* #26 not considered as end of file *)
+
+  sLineBreak = LineEnding;
+  DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
+
+  { Thread count for DLL }
+  Thread_count : longint = 0;
+  System_exception_frame : PEXCEPTION_FRAME =nil;
+
+var
+{ C compatible arguments }
+  argc : longint;
+  argv : ppchar;
+{ Win32 Info }
+  hprevinst,
+  HInstance,
+  MainInstance,
+  DLLreason,DLLparam:longint;
+  Win32StackTop : Dword;
+
+type
+  TDLL_Process_Entry_Hook = function (dllparam : longint) : longbool;
+  TDLL_Entry_Hook = procedure (dllparam : longint);
+
+const
+  Dll_Process_Attach_Hook : TDLL_Process_Entry_Hook = nil;
+  Dll_Process_Detach_Hook : TDLL_Entry_Hook = nil;
+  Dll_Thread_Attach_Hook : TDLL_Entry_Hook = nil;
+  Dll_Thread_Detach_Hook : TDLL_Entry_Hook = nil;
+
+type
+  HMODULE = THandle;
+
+{ Wrappers for some WinAPI calls }
+function EventModify(h: THandle; func: DWORD): LONGBOOL;
+    stdcall; external KernelDLL name 'EventModify';
+function TlsCall(p1, p2: DWORD): DWORD;
+    stdcall; external KernelDLL name 'TlsCall';
+function ResetEvent(h: THandle): LONGBOOL;
+function SetEvent(h: THandle): LONGBOOL;
+function GetCurrentProcessId:DWORD;
+function Win32GetCurrentThreadId:DWORD;
+function TlsAlloc : DWord;
+function TlsFree(dwTlsIndex : DWord) : LongBool;
+
+implementation
+
+{ used by wstrings.inc because wstrings.inc is included before sysos.inc
+  this is put here (FK) }
+(*
+function SysAllocStringLen(psz:pointer;len:dword):pointer;stdcall;
+ external 'oleaut32.dll' name 'SysAllocStringLen';
+
+procedure SysFreeString(bstr:pointer);stdcall;
+ external 'oleaut32.dll' name 'SysFreeString';
+
+function SysReAllocStringLen(var bstr:pointer;psz: pointer;
+  len:dword): Integer; stdcall;external 'oleaut32.dll' name 'SysReAllocStringLen';
+*)
+
+{ include system independent routines }
+{$I system.inc}
+
+{*****************************************************************************
+                      WinAPI wrappers implementation
+*****************************************************************************}
+
+const
+  EVENT_PULSE =     1;
+  EVENT_RESET =     2;
+  EVENT_SET   =     3;
+
+function ResetEvent(h: THandle): LONGBOOL;
+begin
+	ResetEvent := EventModify(h,EVENT_RESET);
+end;
+
+function SetEvent(h: THandle): LONGBOOL;
+begin
+	SetEvent := EventModify(h,EVENT_SET);
+end;
+
+const
+{$ifdef CPUARM}
+  UserKData = $FFFFC800;
+{$else CPUARM}
+  UserKData = $00005800;
+{$endif CPUARM}
+  SYSHANDLE_OFFSET = $004;
+  SYS_HANDLE_BASE	 = 64;
+  SH_CURTHREAD     = 1;
+  SH_CURPROC       = 2;
+
+type
+  PHandle = ^THandle;
+
+function GetCurrentProcessId:DWORD;
+var
+  p: PHandle;
+begin
+  p:=PHandle(UserKData+SYSHANDLE_OFFSET + SH_CURPROC*SizeOf(THandle));
+  GetCurrentProcessId := p^;
+end;
+
+function Win32GetCurrentThreadId:DWORD;
+var
+  p: PHandle;
+begin
+  p:=PHandle(UserKData+SYSHANDLE_OFFSET + SH_CURTHREAD*SizeOf(THandle));
+  Win32GetCurrentThreadId := p^;
+end;
+
+const
+  TLS_FUNCALLOC = 0;
+  TLS_FUNCFREE  = 1;
+
+function TlsAlloc : DWord;
+begin
+  TlsAlloc := TlsCall(TLS_FUNCALLOC, 0);
+end;
+
+function TlsFree(dwTlsIndex : DWord) : LongBool;
+begin
+  TlsFree := LongBool(TlsCall(TLS_FUNCFREE, dwTlsIndex));
+end;
+
+
+{*****************************************************************************
+                              Parameter Handling
+*****************************************************************************}
+
+var
+  ModuleName : array[0..255] of char;
+
+function GetCommandFile:pchar;
+begin
+  GetModuleFileName(0,@ModuleName,255);
+  GetCommandFile:=@ModuleName;
+end;
+
+
+procedure setup_arguments;
+var
+  arglen,
+  count   : longint;
+  argstart,
+  pc,arg  : pchar;
+  quote   : char;
+  argvlen : longint;
+
+  procedure allocarg(idx,len:longint);
+    var
+      oldargvlen : longint;
+    begin
+      if idx>=argvlen then
+       begin
+         oldargvlen:=argvlen;
+         argvlen:=(idx+8) and (not 7);
+         sysreallocmem(argv,argvlen*sizeof(pointer));
+         fillchar(argv[oldargvlen],(argvlen-oldargvlen)*sizeof(pointer),0);
+       end;
+      { use realloc to reuse already existing memory }
+      { always allocate, even if length is zero, since }
+      { the arg. is still present!                     }
+      sysreallocmem(argv[idx],len+1);
+    end;
+
+begin
+  { create commandline, it starts with the executed filename which is argv[0] }
+  { Win32 passes the command NOT via the args, but via getmodulefilename}
+  count:=0;
+  argv:=nil;
+  argvlen:=0;
+  pc:=getcommandfile;
+  Arglen:=0;
+  repeat
+    Inc(Arglen);
+  until (pc[Arglen]=#0);
+  allocarg(count,arglen);
+  move(pc^,argv[count]^,arglen+1);
+  { Setup cmdline variable }
+  cmdline:=GetCommandLine;
+  { process arguments }
+  pc:=cmdline;
+{$IfDef SYSTEM_DEBUG_STARTUP}
+  Writeln(stderr,'Win32 GetCommandLine is #',pc,'#');
+{$EndIf }
+  while pc^<>#0 do
+   begin
+     { skip leading spaces }
+     while pc^ in [#1..#32] do
+      inc(pc);
+     if pc^=#0 then
+      break;
+     { calc argument length }
+     quote:=' ';
+     argstart:=pc;
+     arglen:=0;
+     while (pc^<>#0) do
+      begin
+        case pc^ of
+          #1..#32 :
+            begin
+              if quote<>' ' then
+               inc(arglen)
+              else
+               break;
+            end;
+          '"' :
+            begin
+              if quote<>'''' then
+               begin
+                 if pchar(pc+1)^<>'"' then
+                  begin
+                    if quote='"' then
+                     quote:=' '
+                    else
+                     quote:='"';
+                  end
+                 else
+                  inc(pc);
+               end
+              else
+               inc(arglen);
+            end;
+          '''' :
+            begin
+              if quote<>'"' then
+               begin
+                 if pchar(pc+1)^<>'''' then
+                  begin
+                    if quote=''''  then
+                     quote:=' '
+                    else
+                     quote:='''';
+                  end
+                 else
+                  inc(pc);
+               end
+              else
+               inc(arglen);
+            end;
+          else
+            inc(arglen);
+        end;
+        inc(pc);
+      end;
+     { copy argument }
+     { Don't copy the first one, it is already there.}
+     If Count<>0 then
+      begin
+        allocarg(count,arglen);
+        quote:=' ';
+        pc:=argstart;
+        arg:=argv[count];
+        while (pc^<>#0) do
+         begin
+           case pc^ of
+             #1..#32 :
+               begin
+                 if quote<>' ' then
+                  begin
+                    arg^:=pc^;
+                    inc(arg);
+                  end
+                 else
+                  break;
+               end;
+             '"' :
+               begin
+                 if quote<>'''' then
+                  begin
+                    if pchar(pc+1)^<>'"' then
+                     begin
+                       if quote='"' then
+                        quote:=' '
+                       else
+                        quote:='"';
+                     end
+                    else
+                     inc(pc);
+                  end
+                 else
+                  begin
+                    arg^:=pc^;
+                    inc(arg);
+                  end;
+               end;
+             '''' :
+               begin
+                 if quote<>'"' then
+                  begin
+                    if pchar(pc+1)^<>'''' then
+                     begin
+                       if quote=''''  then
+                        quote:=' '
+                       else
+                        quote:='''';
+                     end
+                    else
+                     inc(pc);
+                  end
+                 else
+                  begin
+                    arg^:=pc^;
+                    inc(arg);
+                  end;
+               end;
+             else
+               begin
+                 arg^:=pc^;
+                 inc(arg);
+               end;
+           end;
+           inc(pc);
+         end;
+        arg^:=#0;
+      end;
+ {$IfDef SYSTEM_DEBUG_STARTUP}
+     Writeln(stderr,'dos arg ',count,' #',arglen,'#',argv[count],'#');
+ {$EndIf SYSTEM_DEBUG_STARTUP}
+     inc(count);
+   end;
+  { get argc and create an nil entry }
+  argc:=count;
+  allocarg(argc,0);
+  { free unused memory }
+  sysreallocmem(argv,(argc+1)*sizeof(pointer));
+end;
+
+
+function paramcount : longint;
+begin
+  paramcount := argc - 1;
+end;
+
+function paramstr(l : longint) : string;
+begin
+  if (l>=0) and (l<argc) then
+    paramstr:=strpas(argv[l])
+  else
+    paramstr:='';
+end;
+
+
+procedure randomize;
+begin
+  randseed:=GetTickCount;
+end;
+
+
+{*****************************************************************************
+                         System Dependent Exit code
+*****************************************************************************}
+
+procedure install_exception_handlers;forward;
+procedure remove_exception_handlers;forward;
+procedure PascalMain;stdcall;external name 'PASCALMAIN';
+procedure fpc_do_exit;stdcall;external name 'FPC_DO_EXIT';
+Procedure ExitDLL(Exitcode : longint); forward;
+procedure asm_exit(Exitcode : longint);external name 'asm_exit';
+
+Procedure system_exit;
+begin
+  { don't call ExitProcess inside
+    the DLL exit code !!
+    This crashes Win95 at least PM }
+  if IsLibrary then
+    ExitDLL(ExitCode);
+  if not IsConsole then
+   begin
+     Close(stderr);
+     Close(stdout);
+     { what about Input and Output ?? PM }
+   end;
+  remove_exception_handlers;
+
+  { call exitprocess, with cleanup as required }
+  asm_exit(exitcode);
+end;
+
+var
+  { value of the stack segment
+    to check if the call stack can be written on exceptions }
+  _SS : Cardinal;
+
+procedure Exe_entry;[public, alias : '_FPC_EXE_Entry'];
+  begin
+     IsLibrary:=false;
+     { install the handlers for exe only ?
+       or should we install them for DLL also ? (PM) }
+     install_exception_handlers;
+     { This strange construction is needed to solve the _SS problem
+       with a smartlinked syswin32 (PFV) }
+     PASCALMAIN;
+     { if we pass here there was no error ! }
+     system_exit;
+  end;
+
+Const
+  { DllEntryPoint  }
+     DLL_PROCESS_ATTACH = 1;
+     DLL_THREAD_ATTACH = 2;
+     DLL_PROCESS_DETACH = 0;
+     DLL_THREAD_DETACH = 3;
+Var
+     DLLBuf : Jmp_buf;
+Const
+     DLLExitOK : boolean = true;
+
+function Dll_entry : longbool;[public, alias : '_FPC_DLL_Entry'];
+var
+  res : longbool;
+
+  begin
+     IsLibrary:=true;
+     Dll_entry:=false;
+     case DLLreason of
+       DLL_PROCESS_ATTACH :
+         begin
+           If SetJmp(DLLBuf) = 0 then
+             begin
+               if assigned(Dll_Process_Attach_Hook) then
+                 begin
+                   res:=Dll_Process_Attach_Hook(DllParam);
+                   if not res then
+                     exit(false);
+                 end;
+               PASCALMAIN;
+               Dll_entry:=true;
+             end
+           else
+             Dll_entry:=DLLExitOK;
+         end;
+       DLL_THREAD_ATTACH :
+         begin
+           inc(Thread_count);
+{$warning Allocate Threadvars !}
+           if assigned(Dll_Thread_Attach_Hook) then
+             Dll_Thread_Attach_Hook(DllParam);
+           Dll_entry:=true; { return value is ignored }
+         end;
+       DLL_THREAD_DETACH :
+         begin
+           dec(Thread_count);
+           if assigned(Dll_Thread_Detach_Hook) then
+             Dll_Thread_Detach_Hook(DllParam);
+{$warning Release Threadvars !}
+           Dll_entry:=true; { return value is ignored }
+         end;
+       DLL_PROCESS_DETACH :
+         begin
+           Dll_entry:=true; { return value is ignored }
+           If SetJmp(DLLBuf) = 0 then
+             begin
+               FPC_DO_EXIT;
+             end;
+           if assigned(Dll_Process_Detach_Hook) then
+             Dll_Process_Detach_Hook(DllParam);
+         end;
+     end;
+  end;
+
+Procedure ExitDLL(Exitcode : longint);
+begin
+    DLLExitOK:=ExitCode=0;
+    LongJmp(DLLBuf,1);
+end;
+
+{$ifdef Set_i386_Exception_handler}
+
+function GetCurrentProcess : dword;
+ stdcall;external 'coredll' name 'GetCurrentProcess';
+
+function ReadProcessMemory(process : dword;address : pointer;dest : pointer;size : dword;bytesread : pdword) :  longbool;
+ stdcall;external 'coredll' name 'ReadProcessMemory';
+
+function is_prefetch(p : pointer) : boolean;
+  var
+    a : array[0..15] of byte;
+    doagain : boolean;
+    instrlo,instrhi,opcode : byte;
+    i : longint;
+  begin
+    result:=false;
+    { read memory savely without causing another exeception }
+    if not(ReadProcessMemory(GetCurrentProcess,p,@a,sizeof(a),nil)) then
+      exit;
+    i:=0;
+    doagain:=true;
+    while doagain and (i<15) do
+      begin
+        opcode:=a[i];
+        instrlo:=opcode and $f;
+        instrhi:=opcode and $f0;
+        case instrhi of
+          { prefix? }
+          $20,$30:
+            doagain:=(instrlo and 7)=6;
+          $60:
+            doagain:=(instrlo and $c)=4;
+          $f0:
+            doagain:=instrlo in [0,2,3];
+          $0:
+            begin
+              result:=(instrlo=$f) and (a[i+1] in [$d,$18]);
+              exit;
+            end;
+          else
+            doagain:=false;
+        end;
+        inc(i);
+      end;
+  end;
+
+
+//
+// Hardware exception handling
+//
+
+{
+  Error code definitions for the Win32 API functions
+
+
+  Values are 32 bit values layed out as follows:
+   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+  +---+-+-+-----------------------+-------------------------------+
+  |Sev|C|R|     Facility          |               Code            |
+  +---+-+-+-----------------------+-------------------------------+
+
+  where
+      Sev - is the severity code
+          00 - Success
+          01 - Informational
+          10 - Warning
+          11 - Error
+
+      C - is the Customer code flag
+      R - is a reserved bit
+      Facility - is the facility code
+      Code - is the facility's status code
+}
+
+const
+  SEVERITY_SUCCESS                = $00000000;
+  SEVERITY_INFORMATIONAL  = $40000000;
+  SEVERITY_WARNING                = $80000000;
+  SEVERITY_ERROR                  = $C0000000;
+
+const
+  STATUS_SEGMENT_NOTIFICATION             = $40000005;
+  DBG_TERMINATE_THREAD                    = $40010003;
+  DBG_TERMINATE_PROCESS                   = $40010004;
+  DBG_CONTROL_C                                   = $40010005;
+  DBG_CONTROL_BREAK                               = $40010008;
+
+  STATUS_GUARD_PAGE_VIOLATION             = $80000001;
+  STATUS_DATATYPE_MISALIGNMENT    = $80000002;
+  STATUS_BREAKPOINT                               = $80000003;
+  STATUS_SINGLE_STEP                              = $80000004;
+  DBG_EXCEPTION_NOT_HANDLED               = $80010001;
+
+  STATUS_ACCESS_VIOLATION                 = $C0000005;
+  STATUS_IN_PAGE_ERROR                    = $C0000006;
+  STATUS_INVALID_HANDLE                   = $C0000008;
+  STATUS_NO_MEMORY                                = $C0000017;
+  STATUS_ILLEGAL_INSTRUCTION              = $C000001D;
+  STATUS_NONCONTINUABLE_EXCEPTION = $C0000025;
+  STATUS_INVALID_DISPOSITION              = $C0000026;
+  STATUS_ARRAY_BOUNDS_EXCEEDED    = $C000008C;
+  STATUS_FLOAT_DENORMAL_OPERAND   = $C000008D;
+  STATUS_FLOAT_DIVIDE_BY_ZERO             = $C000008E;
+  STATUS_FLOAT_INEXACT_RESULT             = $C000008F;
+  STATUS_FLOAT_INVALID_OPERATION  = $C0000090;
+  STATUS_FLOAT_OVERFLOW                   = $C0000091;
+  STATUS_FLOAT_STACK_CHECK                = $C0000092;
+  STATUS_FLOAT_UNDERFLOW                  = $C0000093;
+  STATUS_INTEGER_DIVIDE_BY_ZERO   = $C0000094;
+  STATUS_INTEGER_OVERFLOW                 = $C0000095;
+  STATUS_PRIVILEGED_INSTRUCTION   = $C0000096;
+  STATUS_STACK_OVERFLOW                   = $C00000FD;
+  STATUS_CONTROL_C_EXIT                   = $C000013A;
+  STATUS_FLOAT_MULTIPLE_FAULTS    = $C00002B4;
+  STATUS_FLOAT_MULTIPLE_TRAPS             = $C00002B5;
+  STATUS_REG_NAT_CONSUMPTION              = $C00002C9;
+
+  EXCEPTION_EXECUTE_HANDLER               = 1;
+  EXCEPTION_CONTINUE_EXECUTION    = -1;
+  EXCEPTION_CONTINUE_SEARCH               = 0;
+
+  EXCEPTION_MAXIMUM_PARAMETERS    = 15;
+
+  CONTEXT_X86                                     = $00010000;
+  CONTEXT_CONTROL                         = CONTEXT_X86 or $00000001;
+  CONTEXT_INTEGER                         = CONTEXT_X86 or $00000002;
+  CONTEXT_SEGMENTS                        = CONTEXT_X86 or $00000004;
+  CONTEXT_FLOATING_POINT          = CONTEXT_X86 or $00000008;
+  CONTEXT_DEBUG_REGISTERS         = CONTEXT_X86 or $00000010;
+  CONTEXT_EXTENDED_REGISTERS      = CONTEXT_X86 or $00000020;
+
+  CONTEXT_FULL                            = CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_SEGMENTS;
+
+  MAXIMUM_SUPPORTED_EXTENSION     = 512;
+
+type
+  PFloatingSaveArea = ^TFloatingSaveArea;
+  TFloatingSaveArea = packed record
+          ControlWord : Cardinal;
+          StatusWord : Cardinal;
+          TagWord : Cardinal;
+          ErrorOffset : Cardinal;
+          ErrorSelector : Cardinal;
+          DataOffset : Cardinal;
+          DataSelector : Cardinal;
+          RegisterArea : array[0..79] of Byte;
+          Cr0NpxState : Cardinal;
+  end;
+
+  PContext = ^TContext;
+  TContext = packed record
+      //
+      // The flags values within this flag control the contents of
+      // a CONTEXT record.
+      //
+          ContextFlags : Cardinal;
+
+      //
+      // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
+      // set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
+      // included in CONTEXT_FULL.
+      //
+          Dr0, Dr1, Dr2,
+          Dr3, Dr6, Dr7 : Cardinal;
+
+      //
+      // This section is specified/returned if the
+      // ContextFlags word contains the flag CONTEXT_FLOATING_POINT.
+      //
+          FloatSave : TFloatingSaveArea;
+
+      //
+      // This section is specified/returned if the
+      // ContextFlags word contains the flag CONTEXT_SEGMENTS.
+      //
+          SegGs, SegFs,
+          SegEs, SegDs : Cardinal;
+
+      //
+      // This section is specified/returned if the
+      // ContextFlags word contains the flag CONTEXT_INTEGER.
+      //
+          Edi, Esi, Ebx,
+          Edx, Ecx, Eax : Cardinal;
+
+      //
+      // This section is specified/returned if the
+      // ContextFlags word contains the flag CONTEXT_CONTROL.
+      //
+          Ebp : Cardinal;
+          Eip : Cardinal;
+          SegCs : Cardinal;
+          EFlags, Esp, SegSs : Cardinal;
+
+      //
+      // This section is specified/returned if the ContextFlags word
+      // contains the flag CONTEXT_EXTENDED_REGISTERS.
+      // The format and contexts are processor specific
+      //
+          ExtendedRegisters : array[0..MAXIMUM_SUPPORTED_EXTENSION-1] of Byte;
+  end;
+
+type
+  PExceptionRecord = ^TExceptionRecord;
+  TExceptionRecord = packed record
+          ExceptionCode   : Longint;
+          ExceptionFlags  : Longint;
+          ExceptionRecord : PExceptionRecord;
+          ExceptionAddress : Pointer;
+          NumberParameters : Longint;
+          ExceptionInformation : array[0..EXCEPTION_MAXIMUM_PARAMETERS-1] of Pointer;
+  end;
+
+  PExceptionPointers = ^TExceptionPointers;
+  TExceptionPointers = packed record
+          ExceptionRecord   : PExceptionRecord;
+          ContextRecord     : PContext;
+  end;
+
+{ type of functions that should be used for exception handling }
+  TTopLevelExceptionFilter = function (excep : PExceptionPointers) : Longint;stdcall;
+
+function SetUnhandledExceptionFilter(lpTopLevelExceptionFilter : TTopLevelExceptionFilter) : TTopLevelExceptionFilter;
+        stdcall;external 'kernel32' name 'SetUnhandledExceptionFilter';
+
+const
+  MaxExceptionLevel = 16;
+  exceptLevel : Byte = 0;
+
+var
+  exceptEip       : array[0..MaxExceptionLevel-1] of Longint;
+  exceptError     : array[0..MaxExceptionLevel-1] of Byte;
+  resetFPU        : array[0..MaxExceptionLevel-1] of Boolean;
+
+{$ifdef SYSTEMEXCEPTIONDEBUG}
+procedure DebugHandleErrorAddrFrame(error, addr, frame : longint);
+begin
+  if IsConsole then
+    begin
+      write(stderr,'HandleErrorAddrFrame(error=',error);
+      write(stderr,',addr=',hexstr(addr,8));
+      writeln(stderr,',frame=',hexstr(frame,8),')');
+    end;
+  HandleErrorAddrFrame(error,addr,frame);
+end;
+{$endif SYSTEMEXCEPTIONDEBUG}
+
+procedure JumpToHandleErrorFrame;
+var
+        eip, ebp, error : Longint;
+begin
+        // save ebp
+        asm
+                movl (%ebp),%eax
+                movl %eax,ebp
+        end;
+        if (exceptLevel > 0) then
+                dec(exceptLevel);
+
+        eip:=exceptEip[exceptLevel];
+        error:=exceptError[exceptLevel];
+{$ifdef SYSTEMEXCEPTIONDEBUG}
+        if IsConsole then
+          writeln(stderr,'In JumpToHandleErrorFrame error=',error);
+{$endif SYSTEMEXCEPTIONDEBUG}
+        if resetFPU[exceptLevel] then asm
+                fninit
+                fldcw   fpucw
+        end;
+        { build a fake stack }
+        asm
+{$ifdef REGCALL}
+                movl   ebp,%ecx
+                movl   eip,%edx
+                movl   error,%eax
+                pushl  eip
+                movl   ebp,%ebp // Change frame pointer
+{$else}
+                movl   ebp,%eax
+                pushl  %eax
+                movl   eip,%eax
+                pushl  %eax
+                movl   error,%eax
+                pushl  %eax
+                movl   eip,%eax
+                pushl  %eax
+                movl   ebp,%ebp // Change frame pointer
+{$endif}
+
+{$ifdef SYSTEMEXCEPTIONDEBUG}
+                jmpl   DebugHandleErrorAddrFrame
+{$else not SYSTEMEXCEPTIONDEBUG}
+                jmpl   HandleErrorAddrFrame
+{$endif SYSTEMEXCEPTIONDEBUG}
+        end;
+end;
+
+function syswin32_i386_exception_handler(excep : PExceptionPointers) : Longint;stdcall;
+var
+        frame,
+        res  : longint;
+
+function SysHandleErrorFrame(error, frame : Longint; must_reset_fpu : Boolean) : Longint;
+begin
+        if (frame = 0) then
+                SysHandleErrorFrame:=EXCEPTION_CONTINUE_SEARCH
+        else begin
+                if (exceptLevel >= MaxExceptionLevel) then exit;
+
+                exceptEip[exceptLevel] := excep^.ContextRecord^.Eip;
+                exceptError[exceptLevel] := error;
+                resetFPU[exceptLevel] := must_reset_fpu;
+                inc(exceptLevel);
+
+                excep^.ContextRecord^.Eip := Longint(@JumpToHandleErrorFrame);
+                excep^.ExceptionRecord^.ExceptionCode := 0;
+
+                SysHandleErrorFrame := EXCEPTION_CONTINUE_EXECUTION;
+{$ifdef SYSTEMEXCEPTIONDEBUG}
+                if IsConsole then begin
+                        writeln(stderr,'Exception Continue Exception set at ',
+                                hexstr(exceptEip[exceptLevel],8));
+                        writeln(stderr,'Eip changed to ',
+                                hexstr(longint(@JumpToHandleErrorFrame),8), ' error=', error);
+                end;
+{$endif SYSTEMEXCEPTIONDEBUG}
+        end;
+end;
+
+begin
+        if excep^.ContextRecord^.SegSs=_SS then
+                frame := excep^.ContextRecord^.Ebp
+        else
+                frame := 0;
+        res := EXCEPTION_CONTINUE_SEARCH;
+{$ifdef SYSTEMEXCEPTIONDEBUG}
+        if IsConsole then Writeln(stderr,'Exception  ',
+                hexstr(excep^.ExceptionRecord^.ExceptionCode, 8));
+{$endif SYSTEMEXCEPTIONDEBUG}
+        case cardinal(excep^.ExceptionRecord^.ExceptionCode) of
+                STATUS_INTEGER_DIVIDE_BY_ZERO,
+                STATUS_FLOAT_DIVIDE_BY_ZERO :
+                        res := SysHandleErrorFrame(200, frame, true);
+                STATUS_ARRAY_BOUNDS_EXCEEDED :
+                        res := SysHandleErrorFrame(201, frame, false);
+                STATUS_STACK_OVERFLOW :
+                        res := SysHandleErrorFrame(202, frame, false);
+                STATUS_FLOAT_OVERFLOW :
+                        res := SysHandleErrorFrame(205, frame, true);
+                STATUS_FLOAT_DENORMAL_OPERAND,
+                STATUS_FLOAT_UNDERFLOW :
+                        res := SysHandleErrorFrame(206, frame, true);
+{excep^.ContextRecord^.FloatSave.StatusWord := excep^.ContextRecord^.FloatSave.StatusWord and $ffffff00;}
+                STATUS_FLOAT_INEXACT_RESULT,
+                STATUS_FLOAT_INVALID_OPERATION,
+                STATUS_FLOAT_STACK_CHECK :
+                        res := SysHandleErrorFrame(207, frame, true);
+                STATUS_INTEGER_OVERFLOW :
+                        res := SysHandleErrorFrame(215, frame, false);
+                STATUS_ILLEGAL_INSTRUCTION:
+                  res := SysHandleErrorFrame(216, frame, true);
+                STATUS_ACCESS_VIOLATION:
+                  { Athlon prefetch bug? }
+                  if is_prefetch(pointer(excep^.ContextRecord^.Eip)) then
+                    begin
+                      { if yes, then retry }
+                      excep^.ExceptionRecord^.ExceptionCode := 0;
+                      res:=EXCEPTION_CONTINUE_EXECUTION;
+                    end
+                  else
+                    res := SysHandleErrorFrame(216, frame, true);
+
+                STATUS_CONTROL_C_EXIT:
+                        res := SysHandleErrorFrame(217, frame, true);
+                STATUS_PRIVILEGED_INSTRUCTION:
+                  res := SysHandleErrorFrame(218, frame, false);
+                else
+                  begin
+                    if ((excep^.ExceptionRecord^.ExceptionCode and SEVERITY_ERROR) = SEVERITY_ERROR) then
+                      res  :=  SysHandleErrorFrame(217, frame, true)
+                    else
+                      res := SysHandleErrorFrame(255, frame, true);
+                  end;
+        end;
+        syswin32_i386_exception_handler := res;
+end;
+
+
+procedure install_exception_handlers;
+{$ifdef SYSTEMEXCEPTIONDEBUG}
+var
+        oldexceptaddr,
+        newexceptaddr : Longint;
+{$endif SYSTEMEXCEPTIONDEBUG}
+
+begin
+{$ifdef SYSTEMEXCEPTIONDEBUG}
+        asm
+                movl $0,%eax
+                movl %fs:(%eax),%eax
+                movl %eax,oldexceptaddr
+        end;
+{$endif SYSTEMEXCEPTIONDEBUG}
+        SetUnhandledExceptionFilter(@syswin32_i386_exception_handler);
+{$ifdef SYSTEMEXCEPTIONDEBUG}
+        asm
+                movl $0,%eax
+                movl %fs:(%eax),%eax
+                movl %eax,newexceptaddr
+        end;
+        if IsConsole then
+                writeln(stderr,'Old exception  ',hexstr(oldexceptaddr,8),
+                        ' new exception  ',hexstr(newexceptaddr,8));
+{$endif SYSTEMEXCEPTIONDEBUG}
+end;
+
+procedure remove_exception_handlers;
+begin
+        SetUnhandledExceptionFilter(nil);
+end;
+
+{$else not cpui386 (Processor specific !!)}
+procedure install_exception_handlers;
+begin
+end;
+
+procedure remove_exception_handlers;
+begin
+end;
+
+{$endif Set_i386_Exception_handler}
+
+
+{****************************************************************************
+                      OS dependend widestrings
+****************************************************************************}
+
+function CharUpperBuff(lpsz:LPWSTR; cchLength:DWORD):DWORD; stdcall; external KernelDLL name 'CharUpperBuffW';
+function CharLowerBuff(lpsz:LPWSTR; cchLength:DWORD):DWORD; stdcall; external KernelDLL name 'CharLowerBuffW';
+
+
+function Win32WideUpper(const s : WideString) : WideString;
+  begin
+    result:=s;
+    UniqueString(result);
+    if length(result)>0 then
+      CharUpperBuff(LPWSTR(result),length(result));
+  end;
+
+
+function Win32WideLower(const s : WideString) : WideString;
+  begin
+    result:=s;
+    UniqueString(result);
+    if length(result)>0 then
+      CharLowerBuff(LPWSTR(result),length(result));
+  end;
+
+
+{ there is a similiar procedure in sysutils which inits the fields which
+  are only relevant for the sysutils units }
+procedure InitWin32Widestrings;
+  begin
+    widestringmanager.UpperWideStringProc:=@Win32WideUpper;
+    widestringmanager.LowerWideStringProc:=@Win32WideLower;
+  end;
+
+
+
+{****************************************************************************
+                    Error Message writing using messageboxes
+****************************************************************************}
+
+function MessageBox(w1:longint;l1,l2:pointer;w2:longint):longint;
+   stdcall;external 'coredll' name 'MessageBoxW';
+
+const
+  ErrorBufferLength = 1024;
+var
+  ErrorBuf : array[0..ErrorBufferLength] of char;
+  ErrorLen : longint;
+
+Function ErrorWrite(Var F: TextRec): Integer;
+{
+  An error message should always end with #13#10#13#10
+}
+var
+  p : pchar;
+  i : longint;
+Begin
+  if F.BufPos>0 then
+   begin
+     if F.BufPos+ErrorLen>ErrorBufferLength then
+       i:=ErrorBufferLength-ErrorLen
+     else
+       i:=F.BufPos;
+     Move(F.BufPtr^,ErrorBuf[ErrorLen],i);
+     inc(ErrorLen,i);
+     ErrorBuf[ErrorLen]:=#0;
+   end;
+  if ErrorLen>3 then
+   begin
+     p:=@ErrorBuf[ErrorLen];
+     for i:=1 to 4 do
+      begin
+        dec(p);
+        if not(p^ in [#10,#13]) then
+         break;
+      end;
+   end;
+   if ErrorLen=ErrorBufferLength then
+     i:=4;
+   if (i=4) then
+    begin
+      MessageBox(0,@ErrorBuf,pchar('Error'),0);
+      ErrorLen:=0;
+    end;
+  F.BufPos:=0;
+  ErrorWrite:=0;
+End;
+
+
+Function ErrorClose(Var F: TextRec): Integer;
+begin
+  if ErrorLen>0 then
+   begin
+     MessageBox(0,@ErrorBuf,pchar('Error'),0);
+     ErrorLen:=0;
+   end;
+  ErrorLen:=0;
+  ErrorClose:=0;
+end;
+
+
+Function ErrorOpen(Var F: TextRec): Integer;
+Begin
+  TextRec(F).InOutFunc:=@ErrorWrite;
+  TextRec(F).FlushFunc:=@ErrorWrite;
+  TextRec(F).CloseFunc:=@ErrorClose;
+  ErrorOpen:=0;
+End;
+
+
+procedure AssignError(Var T: Text);
+begin
+  Assign(T,'');
+  TextRec(T).OpenFunc:=@ErrorOpen;
+  Rewrite(T);
+end;
+
+
+procedure SysInitStdIO;
+begin
+  { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
+    displayed in and messagebox }
+  AssignError(stderr);
+  AssignError(stdout);
+  Assign(Output,'');
+  Assign(Input,'');
+  Assign(ErrOutput,'');
+end;
+
+(* ProcessID cached to avoid repeated calls to GetCurrentProcess. *)
+
+var
+  ProcessID: SizeUInt;
+
+function GetProcessID: SizeUInt;
+begin
+ GetProcessID := ProcessID;
+end;
+
+
+const
+   Exe_entry_code : pointer = @Exe_entry;
+   Dll_entry_code : pointer = @Dll_entry;
+
+begin
+  StackLength := InitialStkLen;
+  StackBottom := Sptr - StackLength;
+  { some misc Win32 stuff }
+  hprevinst:=0;
+  if not IsLibrary then
+    HInstance:=getmodulehandle(GetCommandFile);
+  MainInstance:=HInstance;
+  { Setup heap }
+  InitHeap;
+  SysInitExceptions;
+  SysInitStdIO;
+  { Arguments }
+  setup_arguments;
+  { Reset IO Error }
+  InOutRes:=0;
+  ProcessID := GetCurrentProcessID;
+  { threading }
+  InitSystemThreads;
+  { Reset internal error variable }
+  errno:=0;
+  initvariantmanager;
+  initwidestringmanager;
+  InitWin32Widestrings
+end.

+ 67 - 0
rtl/wince/wprt0.as

@@ -0,0 +1,67 @@
+/*
+Startup code for WinCE port of Free Pascal
+Written by Yury Sidorov 2005
+*/
+
+.section .text
+  .balign 4
+.globl mainCRTStartup
+mainCRTStartup:
+.globl _mainCRTStartup
+_mainCRTStartup:
+  mov r0,#1
+  b do_start
+
+.globl WinMainCRTStartup
+WinMainCRTStartup:
+.globl _WinMainCRTStartup
+_WinMainCRTStartup:
+  mov r0,#0
+do_start:
+  ldr r1, _PISCONSOLE
+  strb r0,[r1]
+  bl _FPC_EXE_Entry
+
+.globl asm_exit
+asm_exit:
+  eor   r0,r0,r0
+  bl	exitthread
+  
+_PISCONSOLE:
+  .long U_SYSTEM_ISCONSOLE
+
+.globl exitthread
+exitthread:
+	ldr	ip,.L100
+	ldr pc,[ip]
+.L100:
+  .long .L10
+
+.section .idata$2
+	.rva	.L7
+	.long	0,0
+	.rva	.L6
+	.rva	.L8
+
+.section .idata$4
+.L7:
+	.rva	.L9
+	.long	0
+
+.section .idata$5
+.L8:
+
+.section .idata$5
+.L10:
+	.rva	.L9
+	.long	0
+
+.section .idata$6
+.L9:
+	.short	0
+	.ascii	"ExitThread\000"
+	.balign 2,0
+
+.section .idata$7
+.L6:
+	.ascii	"coredll.dll\000"