Browse Source

Unified Win32 and Win64 Versions of Kernel32 and Objects

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@8216 8c9fc860-2736-0410-a75d-ab315db34111
felixf 7 years ago
parent
commit
f2d6df705d

+ 2 - 5
source/Release.Tool

@@ -283,8 +283,7 @@ PACKAGE Kernel ARCHIVE "Kernel.zip" SOURCE "KernelSrc.zip" DESCRIPTION "A2 Kerne
 	SOLARIS32 { Unix.Glue.Mod Solaris.I386.Unix.Mod }
 	SOLARIS64 { Unix.Glue.Mod Solaris.AMD64.Unix.Mod }
 
-	WIN32 { Windows.I386.Kernel32.Mod }
-	WIN64 { Windows.AMD64.Kernel32.Mod }
+	WIN { Windows.Kernel32.Mod }
 
 	BIOS32 { BIOS.I386.Machine.Mod }
 	BIOS64 { BIOS.AMD64.Machine.Mod }
@@ -304,9 +303,7 @@ PACKAGE Kernel ARCHIVE "Kernel.zip" SOURCE "KernelSrc.zip" DESCRIPTION "A2 Kerne
 	COOP { GarbageCollector.Mod }
 
 	BIOS { BIOS.Objects.Mod Kernel.Mod }
-	WIN32 { Windows.I386.Objects.Mod }
-	WIN64 { Windows.AMD64.Objects.Mod }
-	WIN { Windows.Kernel.Mod }
+	WIN { Windows.Objects.Mod Windows.Kernel.Mod }
 	UNIX { Unix.Objects.Mod Unix.Kernel.Mod }
 	COOP { Coop.Objects.Mod Coop.Kernel.Mod }
 END

+ 0 - 1052
source/Windows.I386.Kernel32.Mod

@@ -1,1052 +0,0 @@
-(* Copyright (c) 1994 - 2000 Emil J. Zeller *)
-
-MODULE Kernel32;   (** AUTHOR "ejz"; PURPOSE "Definition of the Win32 Kernel32 API used by (Win)Aos"; *)
-
-IMPORT SYSTEM;
-
-CONST
-	Generic*= TRUE;
-	
-	(** NIL pointer/address value *)
-	NULL* = 0;
-
-	(** BOOL values *)
-	False* = NULL;  True* = 1;
-
-
-	(** standard handles *)
-	InvalidHandleValue* = -1;  STDInput* = -10;  STDOutput* = -11;
-	STDError* = -12;
-
-	(** generic access rights *)
-	GenericWrite* = 30;  GenericRead* = 31;
-
-	(** file sharing *)
-	FileShareRead* = 0;  FileShareWrite* = 1; FileShareDelete*=2;
-
-	(** file creation *)
-	CreateAlways* = 2;  OpenExisting* = 3;
-
-	(** file attributes *)
-	FileAttributeReadonly* = 0;  FileAttributeHidden* = 1;
-	FileAttributeSystem* = 2;  FileAttributeDirectory* = 4;
-	FileAttributeArchive* = 5;  FileAttributeEncrypted* = 6;
-	FileAttributeNormal* = 7;  FileAttributeTemporary* = 8;
-	FileAttributeSparseFILE* = 9;  FileAttributeReparsePoint* = 10;
-	FileAttributeCompressed* = 11;  FileAttributeOffline* = 12;
-	FileAttributeNotContentIndexed* = 13;
-
-	(** file creation flags *)
-	FileFlagDeleteOnClose*=26;
-	FileFlagRandomAccess* = 28;
-	FileFlagOverlapped* = 30; (** The file or device is being opened or created for asynchronous I/O *)
-	FileFlagWriteThrough*= 31;
-
-	(** move method *)
-	FileBegin* = 0;
-
-	(** move file flags *)
-	MoveFileReplaceExisting* = 0;  MoveFileCopyAllowed* = 1;  MoveFileWriteThrough*= 3;
-	(* (* reason for call values *)
-		DLLProcessDetach = 0; DLLProcessAttach = 1; *)
-
-	(** allocation/free type *)
-	MEMCommit* = 12;  MEMReserve* = 13;  MEMDecommit* = 14;
-	MEMRelease* = 15;  CreateSuspended* = 2;  TLSOutOfIndexes* = -1;
-
-	(** heap allocation options *)
-	HeapNoSerialize* = 2H;
-	HeapGenerateExceptions* = 4H;
-	HeapZeroMemory* = 8H;
-	
-	(** protect (VirtualAlloc) flags *)
-	PageReadWrite* = 2;  PageExecuteReadWrite* = 6;
-
-	(** global memory flags *)
-	GMemMoveable* = 1;  GMemShare* = 13;
-	GMemDDEShare* = GMemShare;
-
-	(** maximum length of full path *)
-	MaxPath* = 260;
-
-	(** specifies the type of a drive *)
-	DriveUnknown* = 0;  DriveNoRootDir* = 1;  DriveRemovable* = 2;
-	DriveFixed* = 3;  DriveRemote* = 4;  DriveCDRom* = 5;
-	DriveRamDisk* = 6;  Infinite* = -1;  WaitObject0* = 0;
-
-	(** thread context and exception information *)
-
-	SizeOf80387Registers* = 80;  ExceptionMaximumParameters* = 15;
-
-	ExceptionGuardPage* = LONGINT(080000001H);
-	ExceptionBreakPoint* = LONGINT(080000003H);
-	ExceptionSingleStep* = LONGINT(080000004H);
-	ExceptionAccessViolation* = LONGINT(0C0000005H);
-	ExceptionIllegalInstruction* = LONGINT(0C000001DH);
-	ExceptionArrayBoundsExceeded* = LONGINT(0C000008CH);
-	ExceptionFltDenormalOperand* = LONGINT(0C000008DH);
-	ExceptionFltDivideByZero* = LONGINT(0C000008EH);
-	ExceptionFltInexactResult* = LONGINT(0C000008FH);
-	ExceptionFltInvalidOperation* = LONGINT(0C0000090H);
-	ExceptionFltOverflow* = LONGINT(0C0000091H);
-	ExceptionFltStackCheck* = LONGINT(0C0000092H);
-	ExceptionFltUndeflow* = LONGINT(0C0000093H);
-	ExceptionIntDivideByZero* = LONGINT(0C0000094H);
-	ExceptionIntOverflow* =LONGINT(0C0000095H);
-	ExceptionPrivInstruction* = LONGINT(0C0000096H);
-	ExceptionStackOverflow* = LONGINT(0C00000FDH);
-
-	ContextIntel = 16;
-	ContextControl* = {0, ContextIntel};   (* SS:SP, CS:IP, FLAGS, BP *)
-	ContextInteger* = {1, ContextIntel};   (* AX, BX, CX, DX, SI, DI *)
-	ContextSegments* = {2, ContextIntel};   (* DS, ES, FS, GS *)
-	ContextFloatingPoint* = {3, ContextIntel};   (* 387 state *)
-	ContextDebugRegisters* = {4, ContextIntel};   (* DB 0-3,6,7 *)
-	ContextFull* = ContextControl + ContextInteger + ContextSegments;
-
-	(** exception frame handler return values *)
-	ExceptionContinueExecution* = -1;  ExceptionContinueSearch* = 0;
-	ExceptionExecuteHandler* = 1;
-
-	(** thread priorities *)
-	ThreadPriorityIdle* = -15;  ThreadPriorityBelowNormal* = -1;
-	ThreadPriorityNormal* = 0;  ThreadPriorityAboveNormal* = 1; ThreadPriorityHighest* = 2;
-	ThreadPriorityTimeCritical* = 15;  ThreadPriorityErrorReturn* = MAX( LONGINT );
-
-
-	(** WaitForSingleObject return values *)
-	WaitTimeout* = 0102H;
-
-	(** SetErrorMode *)
-	SEMFailCriticalErrors* = 0;
-
-	(** DuplicateHandle *)
-	DuplicateCloseSource* = 0;  DuplicateSameAccess* = 1;
-
-	(** StartupInfo flags *)
-	StartFUseShowWindow* = 0;  StartFUseSize* = 1;  StartFUsePosition* = 2;
-
-	(** OSVersionInfo dwPlatformId values *)
-	VerPlatformWin32s* = 0;  VerPlatformWin32Windows* = 1;
-	VerPlatformWin32NT* = 2;
-
-	(** EscapeCommFunction *)
-	SETXOFF* = 1;  SETXON* = 2;  SETRTS* = 3;  CLRRTS* = 4;  SETDTR* = 5;
-	CLRDTR* = 6;  RESETDEV* = 7;  SETBREAK* = 8;  CLRBREAK* = 9;
-
-	(** PurgeComm *)
-	PurgeTXAbort* = 0;  PurgeRXAbort* = 1;  PurgeTXClear* = 2;
-	PurgeRXClear* = 3;
-
-	(** SetCommMask *)
-	EVRXChar* = 0;  EVRXFlag* = 1;  EVTXEmpty* = 2;  EVCTS* = 3;
-	EVDSR* = 4;  EVRLSD* = 5;  EVBreak* = 6;  EVErr* = 7;  EVRing* = 8;
-	EVPErr* = 9;  EVRX80Full* = 10;  EVEvent1* = 11;  EVEvent2* = 12;
-
-	(** GetCommModemStatus *)
-	MSCTSOn* = 4;  MSDSROn* = 5;  MSRingOn* = 6;  MSRLSDOn* = 7;
-	(** DCB *)
-	NoParity* = 0X;  OddParity* = 1X;  EvenParity* = 2X;  MarkParity* = 3X;
-	SpaceParity* = 4X;  OneStopBit* = 0X;  One5StopBits* = 1X;
-	TwoStopBits* = 2X;
-
-	(** GetLastError *)
-	ErrorSuccess* = 0;  ErrorFileNotFound* = 2;  ErrorAccessDenied* = 5;
-	ErrorInvalidParameter* = 87;
-	
-	ErrorIoPending* = 997; (** Overlapped I/O operation is in progress *)
-TYPE
-	(* OutputStringProc* = PROCEDURE (VAR str: ARRAY OF CHAR); *)
-
-	BOOL* = LONGINT;
-
-	HANDLE* = ADDRESS;  HMODULE* = ADDRESS;
-	HINSTANCE* = ADDRESS;  ATOM* = INTEGER;  HGLOBAL* = HANDLE;
-	LPSTR* = ADDRESS;
-	DWORD* = LONGINT;
-
-	(** The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601. *)
-	FileTime* = RECORD
-		dwLowDateTime*, dwHighDateTime*: LONGINT
-	END;
-
-	(** The FindData structure describes a file found by the FindFirstFile or FindNextFile function. *)
-	FindData* = RECORD
-		dwFileAttributes*: WORDSET;
-		ftCreationTime*, ftLastAccessTime*, ftLastWriteTime*: FileTime;
-		nFileSizeHigh*, nFileSizeLow*: LONGINT;
-		dwReserved0*, dwReserved1*: LONGINT;
-		cFileName*: ARRAY MaxPath OF CHAR;
-		cAlternateFileName*: ARRAY 14 OF CHAR
-	END;
-
-	(** The SYSTEMTIME structure represents a date and time using individual members for the month, day, year, weekday,
-			hour, minute, second, and millisecond. *)
-	SystemTime* = RECORD
-		wYear*, wMonth*, wDayOfWeek*, wDay*: INTEGER;
-		wHour*, wMinute*, wSecond*, wMilliseconds*: INTEGER
-	END;
-
-	(** The SMALL_RECT structure defines the coordinates of the upper left and lower right corners of a rectangle. *)
-	SmallRect* = RECORD
-		left*, top*, right*, bottom*: INTEGER
-	END;
-
-
-	(** Critical-section object. *)
-	CriticalSection* = RECORD
-		a, b, c, d, e, f: LONGINT
-	END;
-
-	(** thread context and exception information *)
-
-	FloatingSaveArea* = RECORD
-		ControlWord*, StatusWord*, TagWord*, ErrorOffset*, ErrorSelector*, DataOffset*, DataSelector*: LONGINT;
-		RegisterArea*: ARRAY SizeOf80387Registers OF SYSTEM.BYTE;
-		Cr0NpxState*: LONGINT
-	END;
-
-	Context* = RECORD
-		ContextFlags*: WORDSET;
-		DR0*, DR1*, DR2*, DR3*, DR6*, DR7*: LONGINT;
-		FloatSave*: FloatingSaveArea;
-		GS*, FS*, ES*, DS*: LONGINT;
-		EDI*, ESI*, EBX*, EDX*, ECX*, EAX*: LONGINT;
-		BP*, PC*, CS*, FLAGS*, SP*, SS*: LONGINT; (* whereas BP is EBP and SP is ESP *)
-	END;
-
-	Wow64Context*= RECORD (Context)
-		extension: ARRAY 512 (* MaxWOW64Extension *) OF CHAR;
-	END;
-	
-	ExceptionRecordPtr* = POINTER TO ExceptionRecord;
-	ExceptionRecord* = RECORD
-		ExceptionCode*, ExceptionFlags*: LONGINT;
-		nextExceptionRecord*: ExceptionRecordPtr;
-		ExceptionAddress*: ADDRESS;
-		NumberParameters*: LONGINT;
-		ExceptionInformation*: ARRAY ExceptionMaximumParameters OF LONGINT
-	END;
-
-	ExcpFrmPtr* = ADDRESS;
-	ExcpFrmHandler* = PROCEDURE {WINAPI} ( VAR excpRec: ExceptionRecord;
-																														   excpFrame: ExcpFrmPtr;
-																														   VAR context: Context;
-																														   dispatch: LONGINT ): LONGINT;
-	ExcpFrm* = RECORD
-		link*: ExcpFrmPtr;
-		handler*: ExcpFrmHandler
-	END;
-
-	(** Synchronization Objects *)
-	Object* = POINTER TO RECORD
-		handle*: HANDLE
-	END;
-
-	(** A 64-bit signed integer value. *)
-	LargeInteger* = RECORD
-		LowPart*, HighPart*: LONGINT
-	END;
-
-	(** A 64-bit unsigned integer value. *)
-	ULargeInteger* = LargeInteger;
-
-	(* Added by Alexey *)
-	MemoryStatusEx* = RECORD
-		  dwLength*: LONGINT;
-		  dwMemoryLoad*: LONGINT;
-
-		  ullTotalPhys*: HUGEINT;
-		  ullAvailPhys*: HUGEINT;
-		  ullTotalPageFile*: HUGEINT;
-		  ullAvailPageFile*: HUGEINT;
-		  ullTotalVirtual*: HUGEINT;
-		  ullAvailVirtual*: HUGEINT;
-		  ullAvailExtendedVirtual*: HUGEINT;
-	END;
-
-	(** CreateThread *)
-	ThreadProc* = PROCEDURE {WINAPI} ( lpParameter: ANY ): LONGINT;
-
-	(** CreateProcess *)
-	ProcessInformation* = RECORD
-		hProcess*, hThread*: HANDLE;
-		dwProcessId*, dwThreadId*: LONGINT
-	END;
-
-	(** CreateProcess, GetStartupInfo *)
-	StartupInfo* = RECORD
-		cb*: LONGINT;
-		lpReserved*, lpDesktop*, lpTitle*: LPSTR;
-		dwX*, dwY*, dwXSize*, dwYSize*: LONGINT;
-		dwXCountChars*, dwYCountChars*: LONGINT;
-		dwFillAttribute*: LONGINT;
-		dwFlags*: WORDSET;
-		wShowWindow*, cbReserved2*: INTEGER;
-		lpReserved2*: ADDRESS;
-		hStdInput*, hStdOutput*, hStdError*: HANDLE
-	END;
-
-	(** The OSVersionInfo data structure contains operating system version information. *)
-	OSVersionInfo* = RECORD
-		dwOSVersionInfoSize*, dwMajorVersion*, dwMinorVersion*, dwBuildNumber*, dwPlatformId*: LONGINT;
-		szCSDVersion*: ARRAY 128 OF CHAR
-	END;
-
-	Exception* = RECORD
-		exc*: ExceptionRecord;
-		cont*: Context
-	END;
-
-	CommTimeouts* = RECORD
-		ReadIntervalTimeout*, ReadTotalTimeoutMultiplier*, ReadTotalTimeoutConstant*, WriteTotalTimeoutMultiplier*, WriteTotalTimeoutConstant*: LONGINT
-	END;
-
-	DCB* = RECORD
-		DCBlength*, BaudRate*: LONGINT;
-		flags*: DWORD;
-		wReserved*, XonLim*, XoffLim*: INTEGER;
-		ByteSize*, Parity*, StopBits*, XonChar*, XoffChar*, ErrorChar*, EofChar*, EvtChar*: CHAR;
-		wReserved1*: INTEGER
-	END;
-
-	ComStat* = RECORD
-		status*: DWORD;
-		cbInQue*, cbOutQue*: LONGINT
-	END;
-
-	SystemInfo* = RECORD
-		wProcessorArchitecture*: INTEGER;
-		wReserved: INTEGER;
-		dwPageSize*: LONGINT;
-		lpMinimumApplicationAddress*: LONGINT;
-		lpMaximumApplicationAddress*: LONGINT;
-		dwActiveProcessorMask*: LONGINT;
-		dwNumberOfProcessors*: LONGINT;
-		dwProcessorType*: LONGINT;
-		dwAllocationGranularity*: LONGINT;
-		wProcessorLevel*: INTEGER;
-		wProcessorRevision*: INTEGER;
-	END;
-
-	(*ALEX 2005.10.18 The TIME_ZONE_INFORMATION as defined in winbase.h*)
-	TimeZoneInformation* = RECORD
-		Bias*: LONGINT;
-		StandardName*: ARRAY 32 OF INTEGER;
-		StandardDate*: SystemTime;
-		StandardBias*: LONGINT;
-		DaylightName*: ARRAY 32 OF INTEGER;
-		DaylightDate*: SystemTime;
-		DaylightBias*: LONGINT;
-	END;
-	
-	(** Contains information used in asynchronous (or overlapped) input and output (I/O). *)
-	Overlapped* = RECORD
-		Internal*: LONGINT;
-		InternalHigh*: LONGINT;
-		Offset*: LONGINT;
-		OffsetHigh*: LONGINT;
-		hEvent*: HANDLE;
-	END;
-
-VAR
-	hInstance-: HINSTANCE;   (* init by linker/loader *)
-	isEXE-: BOOLEAN;
-
-	(* the procedure variables getProcAddress and LoadLibrary  must be patched by linker / PE loader *)
-	(** The GetProcAddress function returns the address of the specified exported dynamic-link library (DLL) function.
-			Use the GetProcAddress Oberon wrapper. *)
-	getProcAddress-: PROCEDURE {WINAPI} ( hModule: HMODULE;  CONST  lpProcName: ARRAY   OF CHAR ): ADDRESS;
-	(** The LoadLibrary function maps the specified executable module into the address space of the calling process. *)
-	LoadLibrary-: PROCEDURE {WINAPI} ( CONST lpLibFileName: ARRAY   OF CHAR ): HINSTANCE;   (* must be patched by linker / PE loader *)
-
-
-	(** The AllocConsole function allocates a new console for the calling process. *)
-	AllocConsole-: PROCEDURE {WINAPI} ( ): BOOL;
-	(** The AttachConsole function attaches the calling process to the console of the specified process. *)
-	AttachConsole-: PROCEDURE {WINAPI} (in: LONGINT): BOOL;
-	(**The Beep function generates simple tones on the speaker. The function is synchronous; it does not return control to its caller until the sound finishes.*)
-	Beep-: PROCEDURE {WINAPI} ( dwFreq, dwDuration: LONGINT ): BOOL;
-	(** Marks any outstanding I/O operations for the specified file handle. The function only cancels I/O operations in the current process, regardless of which thread created the I/O operation. *)
-	CancelIoEx-: PROCEDURE {WINAPI} ( hFile: HANDLE; VAR lpOverlapped: Overlapped): BOOL;
-	(** The ClearCommBreak function restores character transmission for a specified communications device and places the transmission line in a nonbreak state. *)
-	ClearCommBreak-: PROCEDURE {WINAPI} ( hFile: HANDLE ): BOOL;
-	(** The ClearCommError function retrieves information about a communications error and reports the current status of a communications device. *)
-	ClearCommError-: PROCEDURE {WINAPI} ( hFile: HANDLE;  VAR lpErrors: DWORD;  VAR lpStat: ComStat ): BOOL;
-	(** The CloseHandle function closes an open object handle. *)
-	CloseHandle-: PROCEDURE {WINAPI} ( hObject: HANDLE ): BOOL;
-	(** The CopyFile function copies an existing file to a new file. *)
-	CopyFile-: PROCEDURE {WINAPI} ( VAR lpExistingFileName, lpNewFileName: ARRAY  OF CHAR; bFailIfExists: BOOL ): BOOL;
-	(** The CreateDirectory function creates a new directory. *)
-	CreateDirectory-: PROCEDURE {WINAPI} ( VAR lpPathName: ARRAY   OF CHAR;
-																		 lpSecurityAttributes: ANY ): BOOL;
-	(** The CreateEvent function creates a named or unnamed event object. *)
-	CreateEvent-: PROCEDURE {WINAPI} ( lpEventAttributes: ANY;
-																   bManualReset, bInitialState: BOOL;
-																   CONST lpName: ARRAY   OF CHAR ): HANDLE;
-	(** The CreateFile function creates or opens the following objects and returns a handle that can be used to access the object:
-		 files, pipes, mailslots, communications resources, disk devices (Windows NT only), consoles, directories (open only) *)
-	CreateFile-: PROCEDURE {WINAPI} ( CONST lpFileName: ARRAY   OF CHAR;
-																dwDesiredAccess, dwShareMode: WORDSET;
-																lpSecurityAttributes: ANY;
-																dwCreationDistribution: LONGINT;
-																dwFlagsAndAttributes: WORDSET;
-																hTemplateFile: HANDLE ): HANDLE;
-	(** The CreateProcess function creates a new process and its primary thread. The new process executes the specified
-			executable file. *)
-	CreateProcess-: PROCEDURE {WINAPI} ( CONST lpApplicationName, lpCommandLine: ARRAY   OF CHAR;
-																	   lpProcessAttributes, lpThreadAttributes: ANY;
-																	   bInheritHandles: BOOL;
-																	   dwCreationFlags: LONGINT;
-																	   lpEnvironment: ANY;
-																	   VAR lpCurrentDirectory: ARRAY   OF CHAR;
-																	   VAR lpStartupInfo: StartupInfo;
-																	   VAR lpProcessInformation: ProcessInformation ): BOOL;
-	(** The CreateSemaphore function creates or opens a named or unnamed semaphore object. *)
-	CreateSemaphore-: PROCEDURE {WINAPI} ( lpThreadAttributes: ADDRESS; lInitialCount: LONGINT; lMaximumCount: LONGINT; lpName: LPSTR): HANDLE;
-	(** The CreateThread function creates a thread to execute within the address space of the calling process. *)
-	CreateThread-: PROCEDURE {WINAPI} ( lpThreadAttributes: ADDRESS;
-																	  dwStackSize: LONGINT;
-																	  lpStartAddress: ThreadProc;
-																	  lpParameter: ANY;  dwCreationFlags: WORDSET;
-																	  VAR lpThreadId: LONGINT ): HANDLE;
-	(** The DeleteCriticalSection function releases all resources used by an unowned critical section object. *)
-	DeleteCriticalSection-: PROCEDURE {WINAPI} ( VAR lpCriticalSection: CriticalSection );
-	(** The DeleteFile function deletes an existing file. *)
-	DeleteFile-: PROCEDURE {WINAPI} ( VAR lpFileName: ARRAY   OF CHAR ): BOOL;
-	(** The DisableThreadLibraryCalls function disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications
-			for the dynamic-link library (DLL) specified by hLibModule. *)
-	DisableThreadLibraryCalls-: PROCEDURE {WINAPI} ( hLibModule: HMODULE ): BOOL;
-	(** The DuplicateHandle function duplicates an object handle. *)
-	DuplicateHandle-: PROCEDURE {WINAPI} ( hSourceProcessHandle, hSourceHandle, hTargetProcessHandle: HANDLE;
-																			 VAR lpTargetHandle: HANDLE;
-																			 dwDesiredAccess: WORDSET;
-																			 bInheritHandle: BOOL;
-																			 dwOptions: WORDSET ): BOOL;
-	(** The EnterCriticalSection function waits for ownership of the specified critical section object. *)
-	EnterCriticalSection-: PROCEDURE {WINAPI} ( VAR lpCriticalSection: CriticalSection );
-	
-	(** The EscapeCommFunction function directs a specified communications device to perform an extended function. *)
-	EscapeCommFunction-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-																					  dwFunc: LONGINT ): BOOL;
-	(** The ExitProcess function ends a process and all its threads. *)
-	ExitProcess-: PROCEDURE {WINAPI} ( uExitCode: LONGINT );
-	(** The ExitThread function ends a thread. *)
-	ExitThread-: PROCEDURE {WINAPI} ( dwExitCode: LONGINT );
-	(** The FileTimeToLocalFileTime function converts a file time based on the Coordinated Universal Time (UTC) to a
-			local file time. *)
-	FileTimeToLocalFileTime-: PROCEDURE {WINAPI} ( VAR lpFileTime: FileTime;
-																						   VAR lpLocalFileTime: FileTime ): BOOL;
-	(** The FileTimeToSystemTime function converts a 64-bit file time to system time format. *)
-	FileTimeToSystemTime-: PROCEDURE {WINAPI} ( VAR lpFileTime: FileTime;
-																					   VAR lpSystemTime: SystemTime ): BOOL;
-	(** The FindClose function closes the specified search handle. *)
-	FindClose-: PROCEDURE {WINAPI} ( hFindFile: HANDLE ): BOOL;
-	(** The FindFirstFile function searches a directory for a file whose name matches the specified filename. *)
-	FindFirstFile-: PROCEDURE {WINAPI} ( VAR lpFileName: ARRAY   OF CHAR;
-																	 VAR lpFindFileDate: FindData ): HANDLE;
-	(** The FindNextFile function continues a file search from a previous call to the FindFirstFile function. *)
-	FindNextFile-: PROCEDURE {WINAPI} ( hFindFile: HANDLE;
-																	  VAR lpFindFileDate: FindData ): BOOL;
-	(** The FlushFileBuffers function clears the buffers for the specified file and causes all buffered data to be written
-			to the file. *)
-	FlushFileBuffers-: PROCEDURE {WINAPI} ( hFile: HANDLE ): BOOL;
-	(** The FreeConsole function detaches the calling process from its console *)
-	FreeConsole-: PROCEDURE {WINAPI} ( ): BOOL;
-	(** The FreeLibrary function decrements the reference count of the loaded dynamic-link library (DLL) module.
-			When the reference count reaches zero, the module is unmapped from the address space of the calling process
-			and the handle is no longer valid. *)
-	FreeLibrary-: PROCEDURE {WINAPI} ( hLibModule: HMODULE ): BOOL;
-	(** The GetCommandLine function returns a pointer to the command-line string for the current process. *)
-	GetCommandLine-: PROCEDURE {WINAPI} ( ): LPSTR;
-	(** The GetCommModemStatus function retrieves modem control-register values. *)
-	GetCommModemStatus-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-																						VAR lpModemStat: WORDSET ): BOOL;
-	(** The GetCommState function retrieves the current control settings for a specified communications device. *)
-	GetCommState-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-																		 VAR lpDCB: DCB ): BOOL;
-	(** The GetComputerName function retrieves the NetBIOS name of the local computer. *)
-	GetComputerName-: PROCEDURE {WINAPI} ( VAR lpBuffer: ARRAY   OF CHAR;
-																			    VAR lpnSize: LONGINT ): BOOL;
-	(** The GetCurrentDirectory function retrieves the current directory for the current process. *)
-	GetCurrentDirectory-: PROCEDURE {WINAPI} ( nBufferLength: LONGINT;
-																				 VAR lpBuffer: ARRAY   OF CHAR ): LONGINT;
-	(** The GetConsoleWindow function retrieves the window handle used by the console associated with the calling process. *)
-	(*
-	GetConsoleWindow-: PROCEDURE{WINAPI} (): LONGINT ;
-	(** The GetCurrentProcess function returns a pseudohandle for the current process. *)
-	not in smaller versions than Win2000!
-	*)
-	GetCurrentProcess-: PROCEDURE {WINAPI} ( ): HANDLE;
-	(** The GetCurrentProcessId function returns the process identifier of the calling process. *)
-	GetCurrentProcessId-: PROCEDURE {WINAPI} ( ): LONGINT;
-	(** The GetCurrentThread function returns a pseudohandle for the current thread. *)
-	GetCurrentThread-: PROCEDURE {WINAPI} ( ): HANDLE;
-	(** The GetCurrentThreadId function returns the thread identifier of the calling thread. *)
-	GetCurrentThreadId-: PROCEDURE {WINAPI} ( ): LONGINT;
-	(** The GetDiskFreeSpace function retrieves information about the specified disk, including the amount of
-			free space on the disk. *)
-	GetDiskFreeSpace-: PROCEDURE {WINAPI} ( VAR lpRootPathName: ARRAY   OF CHAR;
-																			  VAR lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: LONGINT ): BOOL;
-	(** The GetDriveType function determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or
-			network drive. *)
-	GetDriveType-: PROCEDURE {WINAPI} ( VAR lpRootPathName: ARRAY   OF CHAR ): LONGINT;
-	(** The GetExitCodeProcess function retrieves the termination status of the specified process. *)
-	GetExitCodeProcess-: PROCEDURE {WINAPI} ( hProcess: HANDLE;
-																				  VAR lpExitCode: LONGINT ): BOOL;
-	(** The GetFileAttributes function returns attributes for a specified file or directory. *)
-	GetFileAttributes-: PROCEDURE {WINAPI} ( VAR lpFileName: ARRAY   OF CHAR ): WORDSET;
-	(** The GetFileSize function retrieves the size, in bytes, of the specified file. *)
-	GetFileSize-: PROCEDURE {WINAPI} ( hFile: HANDLE;  VAR lpFileSizeHigh: LONGINT ): LONGINT;
-	GetFileSizeEx-: PROCEDURE {WINAPI} ( hFile: HANDLE;  VAR lpFileSize: HUGEINT ): BOOL;
-	(** The GetFileTime function retrieves the date and time that a file was created, last accessed, and last modified. *)
-	GetFileTime-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-																	VAR lpCreationTime, lpLastAccessTime, lpLastWriteTime: FileTime ): BOOL;
-	(** The GetFullPathName function retrieves the full path and filename of a specified file. *)
-	GetFullPathName-: PROCEDURE {WINAPI} ( CONST lpFileName: ARRAY   OF CHAR;
-																			  nBufferLength: LONGINT;
-																			  VAR lpBuffer: ARRAY   OF CHAR;
-																			  lpFilePart: LPSTR ): LONGINT;
-	(** The GetLastError function returns the calling thread's last-error code value. *)
-	GetLastError-: PROCEDURE {WINAPI} ( ): LONGINT;
-	(** The GetLocalTime function retrieves the current local date and time. *)
-	GetLocalTime-: PROCEDURE {WINAPI} ( VAR lpSystemTime: SystemTime );
-	(** The GetLogicalDriveStrings function retrieves a string containing the drive letters. *)  (*ALEX 2005.02.10*)
-	GetLogicalDriveStrings-: PROCEDURE {WINAPI} ( nBufferLength: LONGINT;
-																					   VAR lpBuffer: ARRAY   OF CHAR ): LONGINT;
-	(** The GetModuleFileName function retrieves the full path and filename for the executable file containing the
-			specified module. *)
-	(* The GetLogicalDrives function retrieves a bitmask representing the currently available disk drives.
-*)
-
-	GetLogicalDrives-: PROCEDURE {WINAPI} ( ): WORDSET;
-	GetModuleFileName-: PROCEDURE {WINAPI} ( hModule: HMODULE;
-																				    VAR lpFileName: ARRAY   OF CHAR;
-																				    nSize: LONGINT ): LONGINT;
-	(** The GetModuleHandle function returns a module handle for the specified module if the file has been mapped
-			into the address space of the calling process. *)
-	GetModuleHandle-: PROCEDURE {WINAPI} ( CONST lpModuleName: ARRAY   OF CHAR ): HMODULE;
-	
-	(** Retrieves the results of an overlapped operation on the specified file, named pipe, or communications device. 
-			To specify a timeout interval or wait on an alertable thread. *)
-	GetOverlappedResult-: PROCEDURE {WINAPI} ( hFile: HANDLE; VAR lpOverlapped: Overlapped; VAR lpNumberOfBytesTransferred: LONGINT; bWait: BOOL ): BOOL;
-	
-	(** The GetPrivateProfileString function retrieves a string from the specified section in an initialization file.*)
-	GetPrivateProfileString-: PROCEDURE {WINAPI} ( CONST lpAppName: ARRAY OF CHAR;
-																			CONST lpKeyName: ARRAY OF CHAR;
-																			CONST lpDefault: ARRAY OF CHAR;
-																			CONST lpReturnedString: ARRAY OF CHAR;
-																			nSize: LONGINT;
-																			CONST lpFileName: ARRAY OF CHAR): LONGINT;
-	(** The GetProcessAffinityMask function retrieves the process affinity mask for the specified process and the system affinity mask for the system. *)
-	GetProcessAffinityMask- : PROCEDURE {WINAPI} ( hProcess: HANDLE; lpProcessAffinityMask: ADDRESS;  lpSystemAffinityMask: ADDRESS ): BOOL;
-	(** The GetProcessHeap function retrieves a handle to the default heap of the calling process. This handle can then be used in subsequent calls to the heap functions. *)
-	GetProcessHeap- : PROCEDURE {WINAPI} (): HANDLE;
-	(** The GetProcessTimes function returns the times spent in kernel mode, user mode ... for the specified process *)
-	GetProcessTimes- : PROCEDURE {WINAPI} (CONST hProcess: HANDLE; VAR lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: FileTime ): LONGINT;
-	(** The GetStartupInfo function retrieves the contents of the StartupInfo structure that was specified when
-			the calling process was created. *)
-	GetStartupInfo-: PROCEDURE {WINAPI} ( VAR lpStartupInfo: StartupInfo );
-	(** Retrieves information about the current system. *)
-	GetSystemInfo-: PROCEDURE {WINAPI} ( VAR lpSystemInfo: SystemInfo );
-	(** The GetStdHandle function returns a handle for the standard input, standard output, or standard error device. *)
-	GetStdHandle-: PROCEDURE {WINAPI} ( nStdHandle: LONGINT ): HANDLE;
-	(** The GetSystemTime function retrieves the current system date and time. The system time is expressed in
-			Coordinated Universal Time (UTC). *)
-	GetSystemTime-: PROCEDURE {WINAPI} ( VAR lpSystemTime: SystemTime );
-	(** The GetTempFileName function creates a name for a temporary file. The filename is the concatenation of
-			specified path and prefix strings, a hexadecimal string formed from a specified integer, and the .TMP extension. *)
-	GetTempFileName-: PROCEDURE {WINAPI} ( VAR lpPathName, lpPrefixName: ARRAY   OF CHAR;
-																			   uUnique: LONGINT;
-																			   VAR lpTempFileName: ARRAY   OF CHAR ): LONGINT;
-	(** The GetTempPath function retrieves the path of the directory designated for temporary files. *)
-	GetTempPath-: PROCEDURE {WINAPI} ( nBufferLength: LONGINT;
-																	   VAR lpBuffer: ARRAY   OF CHAR ): LONGINT;
-	(** The GetThreadContext function retrieves the context of the specified thread. *)
-	GetThreadContext-: PROCEDURE {WINAPI} ( hThread: HANDLE;
-																			  VAR lpContext: Context ): BOOL;
-
-	(** The GetThreadContext function retrieves the context of the specified thread. *)
-	Wow64GetThreadContext-: PROCEDURE {WINAPI} ( hThread: HANDLE;
-																			  VAR lpContext: Wow64Context ): BOOL;
-
-	(** The GetThreadPriority function returns the priority value for the specified thread. This value, together with
-			the priority class of the thread's process, determines the thread's base-priority level. *)
-	GetThreadPriority-: PROCEDURE {WINAPI} ( hThread: HANDLE ): LONGINT;
-	(** The GetThreadTimes function returns the times spent in kernel mode, user mode ... specified thread.  *)
-	GetThreadTimes-: PROCEDURE {WINAPI} ( hThread: HANDLE;
-																		   VAR lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: FileTime ): LONGINT;   (*ALEX 2005.12.12*)
-	 (** The GetTickCount function retrieves the number of milliseconds that have elapsed since the system was started. *)
-	GetTickCount-: PROCEDURE {WINAPI} ( ): LONGINT;
-	(** The GetTimeZoneInformation function retrieves information about timezone setup. *)  (*ALEX 2005.10.18*)
-	GetTimeZoneInformation-: PROCEDURE {WINAPI} ( VAR lpTimeZoneInformation: TimeZoneInformation ): LONGINT;
-	(** The GetWindowsDir function retrieves the path of the Windows directory. *) (*ALEX 2006.06.05*)
-	GetWindowsDirectory-: PROCEDURE {WINAPI} (  VAR lpBuffer: ARRAY   OF CHAR; nBufferLength: LONGINT ): LONGINT;
-	(** The GetVersion function returns the current version number of the operating system. *)
-	GetVersion-: PROCEDURE {WINAPI} ( ): LONGINT;
-	(** The GetVersionEx function obtains extended information about the version of the operating system that is
-			currently running. *)
-	GetVersionEx-: PROCEDURE {WINAPI} ( VAR lpVersionInfo: OSVersionInfo ): BOOL;
-	(*The GetVolumeInformation function retrieves information about a file system and volume that have a specified
-	root directory. *)
-
-	GetVolumeInformation-: PROCEDURE {WINAPI} ( VAR lpRootPathName: ARRAY   OF CHAR;
-																					    VAR lpVolumeNameBuffer: ARRAY   OF CHAR;
-																					    nVolumeNameSize: LONGINT;
-																					    VAR lpVolumeSerialNumber: LONGINT;
-																					    VAR lpMaximumComponentLength: LONGINT;
-																					    VAR lpFileSystemFlags: LONGINT;
-																					    VAR lpFileSystemNameBuffer: ARRAY   OF CHAR;
-																					    nFileSystemNameSize: LONGINT ): LONGINT;
-
-	(** The GlobalAddAtom function adds a character string to the global atom table and returns a unique value
-			(an atom) identifying the string. *)
-	GlobalAddAtom-: PROCEDURE {WINAPI} ( VAR lpString: ARRAY   OF CHAR ): ATOM;
-	(** The GlobalAlloc function allocates the specified number of bytes from the heap. *)
-	GlobalAlloc-: PROCEDURE {WINAPI} ( uFlags: WORDSET;  dwBytes: LONGINT ): HGLOBAL;
-	(** The GlobalDeleteAtom function decrements the reference count of a global string atom. *)
-	GlobalDeleteAtom-: PROCEDURE {WINAPI} ( nAtom: ATOM ): ATOM;
-	(** The GlobalLock function locks a global memory object and returns a pointer to the first byte of the
-			object's memory block. *)
-	GlobalLock-: PROCEDURE {WINAPI} ( hMem: HGLOBAL ): ADDRESS;
-
-	(* Added by Alexey *)
-	GlobalMemoryStatusEx-: PROCEDURE {WINAPI} (VAR lpBuffer: MemoryStatusEx): BOOL;
-
-	(** The GlobalReAlloc function changes the size or attributes of a specified global memory object. *)
-	GlobalReAlloc-: PROCEDURE {WINAPI} ( hMem: HGLOBAL;  dwBytes: LONGINT;
-																		uFlags: DWORD ): HGLOBAL;
-	(** The GlobalSize function retrieves the current size, in bytes, of the specified global memory object. *)
-	GlobalSize-: PROCEDURE {WINAPI} ( hMem: HGLOBAL ): LONGINT;
-	(** The GlobalUnlock function decrements the lock count associated with a memory object that was allocated with
-			the GMEM_MOVEABLE flag. *)
-	GlobalUnlock-: PROCEDURE {WINAPI} ( hMem: HGLOBAL ): BOOL;
-	(** The HeapAlloc function allocates a block of memory from a heap. The allocated memory is not movable. *)
-	HeapAlloc-: PROCEDURE {WINAPI} ( hHeap: HANDLE; dwFlags: LONGINT; size: SIZE): ADDRESS;
-	(** The HeapFree function frees a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function. *)
-	HeapFree-: PROCEDURE {WINAPI} ( hHeap: HANDLE; dwFlags: LONGINT; lpMem: ADDRESS): ADDRESS;
-	(** The InitializeCriticalSection function initializes a critical section object. *)
-	InitializeCriticalSection-: PROCEDURE {WINAPI} ( VAR lpCriticalSection: CriticalSection );
-	(** The InterlockedDecrement function both decrements (decreases by one) the value of the specified 32-bit
-			variable and checks the resulting value. *)
-	InterlockedDecrement-: PROCEDURE {WINAPI} ( VAR lpAddend: LONGINT ): LONGINT;
-	(** The InterlockedIncrement function both increments (increases by one) the value of the specified 32-bit variable
-			and checks the resulting value. *)
-	InterlockedIncrement-: PROCEDURE {WINAPI} ( VAR lpAddend: LONGINT ): LONGINT;
-
-	(** The LeaveCriticalSection function releases ownership of the specified critical section object. *)
-	LeaveCriticalSection-: PROCEDURE {WINAPI} ( VAR lpCriticalSection: CriticalSection );
-		
-	(** The LocalFileTimeToFileTime function converts a local file time to a file time based on the Coordinated
-			Universal Time (UTC). *)
-	LocalFileTimeToFileTime-: PROCEDURE {WINAPI} ( VAR lpLocalFileTime: FileTime;
-																						   VAR lpFileTime: FileTime ): BOOL;
-	(** The MoveFileEx function renames an existing file or directory. *)
-	MoveFileEx-: PROCEDURE {WINAPI} ( VAR lpExistingFileName, lpNewFileName: ARRAY   OF CHAR;
-																    dwFlags: WORDSET ): BOOL;
-	(** The OutputDebugString function sends a string to the debugger for the current application. *)
-	outputDebugString-: PROCEDURE {WINAPI} ( CONST lpOutputString: ARRAY   OF CHAR );
-
-	(* The IsDebuggerPresent Function determines whether the calling process is being debugged by a user-mode debugger. *)
-
-	IsDebuggerPresent-: PROCEDURE {WINAPI}(): BOOL;
-
-
-	(** The PurgeComm function discards all characters from the output or input buffer of a specified communications resource. *)
-	PurgeComm-: PROCEDURE {WINAPI} ( hFile: HANDLE;  dwFlags: WORDSET ): BOOL;
-	(** The QueryDosDevice function retrieves information about MS-DOS device names. *)
-	QueryDosDevice-: PROCEDURE {WINAPI} ( lpDeviceName: ARRAY   OF CHAR;
-																		   VAR lpTargetPath: ARRAY   OF CHAR;
-																		   ucchMax: LONGINT ): LONGINT;
-	(** The QueryPerformanceCounter function retrieves the current value of the high-resolution
-	performance counter, if one exists. *)
-	QueryPerformanceCounter-: PROCEDURE {WINAPI} ( VAR lpPerformaceCount: LargeInteger ): BOOL;
-	(** The QueryPerformanceFrequency function retrieves the frequency of the high-resolution
-			performance counter, if one exists. *)
-	QueryPerformanceFrequency-: PROCEDURE {WINAPI} ( VAR lpFrequency: LargeInteger ): BOOL;
-
-	(** Retrieves the cycle time for the specified thread (both user and kernel mode, Windows Vista and newer) *)
-	QueryThreadCycleTime- : PROCEDURE {WINAPI} (hThread : HANDLE; VAR cycleTime : HUGEINT) : BOOL;
-	(** The ReadFile function reads data from a file, starting at the position indicated by the file pointer. *)
-	ReadFile-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-															  VAR lpBuffer: ARRAY OF SYSTEM.BYTE;
-															  nNumberOfBytesToRead: LONGINT;
-															  VAR lpNumberOfBytesRead: LONGINT;
-															  VAR lpOverlapped: Overlapped ): BOOL;
-
-	(** The ReadProcessMemory function reads data from an area of memory in a specified process. *)
-	ReadProcessMemory-: PROCEDURE {WINAPI} ( hProcess: HANDLE;
-																				   lpBaseAddress: ADDRESS;
-																				   VAR lpBuffer: ARRAY   OF SYSTEM.BYTE;
-																				   nSize: LONGINT;
-																				   VAR lpNumberOfBytesRead: LONGINT ): BOOL;
-	(** The ReleaseSemaphore function increases the count of the specified semaphore object by a specified amount. *)
-	ReleaseSemaphore-: PROCEDURE {WINAPI} ( hSemaphore: HANDLE; lReleaseCount: LONGINT; lpPreviousCount: ADDRESS): BOOL;
-	(** The RemoveDirectory function deletes an existing empty directory. *)
-	RemoveDirectory-: PROCEDURE {WINAPI} ( VAR lpPathName: ARRAY   OF CHAR ): BOOL;
-	(** The ResetEvent function sets the state of the specified event object to nonsignaled. *)
-	ResetEvent-: PROCEDURE {WINAPI} ( hEvent: HANDLE ): BOOL;
-	(** The ResumeThread function decrements a thread's suspend count. *)
-	ResumeThread-: PROCEDURE {WINAPI} ( hThread: HANDLE ): LONGINT;
-	(** The SearchPath function searches for the specified file. *)
-	SearchPath-: PROCEDURE {WINAPI} ( CONST lpPath, lpFileName, lpExtension: ARRAY   OF CHAR;
-																  nBufferLength: LONGINT;
-																  VAR lpBuffer: ARRAY   OF CHAR;
-																  VAR lpFilePart: LPSTR ): LONGINT;
-	(** The SetCommBreak function suspends character transmission for a specified communications device and places the transmission line in a break state until the ClearCommBreak function is called. *)
-	SetCommBreak-: PROCEDURE {WINAPI} ( hFile: HANDLE ): BOOL;
-	(** The SetCommMask function specifies a set of events to be monitored for a communications device. *)
-	SetCommMask-: PROCEDURE {WINAPI} ( hFile: HANDLE;  dwEvtMask: DWORD ): BOOL;
-	(** The SetCommState function configures a communications device according to the specifications in a device-control block (a DCB structure)*)
-	SetCommState-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-																	    VAR lpDCB: DCB ): BOOL;
-	(** The SetCommTimeouts function sets the time-out parameters for all read and write operations on a specified communications device. *)
-	SetCommTimeouts-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-																			    VAR lpCommTimeouts: CommTimeouts ): BOOL;
-	(** the SetConsoleCursorPosition  sets the cursor position in the specified console screen buffer. *)
-	SetConsoleCursorPosition-: PROCEDURE {WINAPI} ( hConsoleOutput: HANDLE;  dwCursorPosition:  (* imitate Coord=RECORD x,y: INTEGER END; *) LONGINT ): BOOL;
-	(** The SetConsoleScreenBufferSize function changes the size of the specified console screen buffer. *)
-	SetConsoleScreenBufferSize-: PROCEDURE {WINAPI} ( hConsoleOuput: HANDLE;
-																							   dwSize: LONGINT ): BOOL;
-	(** The SetConsoleTextAttribute function sets the attributes of characters written to the console screen buffer by the WriteFile or WriteConsole function, or echoed by the ReadFile or ReadConsole function. *)
-	SetConsoleTextAttribute-: PROCEDURE {WINAPI} (hConsoleOutput: HANDLE; wAttributes: LONGINT): BOOL;
-	(** The SetConsoleTitle function sets the title bar string for the current console window. *)
-	SetConsoleTitle-: PROCEDURE {WINAPI} ( VAR lpConsoleTitle: ARRAY   OF CHAR ): BOOL;
-	(** The SetConsoleWindowInfo function sets the current size and position of a console screen buffer's window. *)
-	SetConsoleWindowInfo-: PROCEDURE {WINAPI} ( hConsoleOuput: HANDLE;
-																						 bAbsolute: BOOL;
-																						 VAR lpConsoleWindow: SmallRect ): BOOL;
-	(** The SetCurrentDirectory function changes the current directory for the current process. *)
-	SetCurrentDirectory-: PROCEDURE {WINAPI} ( VAR lpPathName: ARRAY   OF CHAR ): BOOL;
-	(** The SetErrorMode function controls whether the system will handle the specified types of serious errors,
-			or whether the process will handle them. *)
-	SetErrorMode-: PROCEDURE {WINAPI} ( uMode: DWORD ): LONGINT;
-	(** The SetEndOfFile function moves the end-of-file (EOF) position for the specified file to the current position of the file pointer. *)
-	SetEndOfFile-: PROCEDURE {WINAPI} ( hFile: HANDLE ): BOOL;
-	(** The SetEvent function sets the state of the specified event object to signaled. *)
-	SetEvent-: PROCEDURE {WINAPI} ( hEvent: HANDLE ): BOOL;
-	(** The SetFileAttributes function sets a file's attributes. *)
-	SetFileAttributes-: PROCEDURE {WINAPI} ( VAR lpFileName: ARRAY   OF CHAR;
-																			dwFileAttributes: WORDSET ): BOOL;
-	(** The SetFilePointer function moves the file pointer of an open file. *)
-	SetFilePointer-: PROCEDURE {WINAPI} ( hFile: HANDLE;  lDistanceToMove: LONGINT;
-																	    VAR lpDistanceToMoveHigh: LONGINT;
-																	    dwMoveMethod: LONGINT ): LONGINT;
-	SetFilePointerEx-: PROCEDURE {WINAPI} ( hFile: HANDLE;  lDistanceToMove: HUGEINT;
-																		VAR lpNewFilePointer: HUGEINT;
-																		dwMoveMethod: LONGINT ): BOOL;
-	(** The SetFileTime function sets the date and time that a file was created, last accessed, or last modified. *)
-	SetFileTime-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-																    VAR lpCreationTime, lpLastAccessTime, lpLastWriteTime: FileTime ): BOOL;
-	(** The SetLocalTime function sets the current local time and date. *)
-	SetLocalTime-: PROCEDURE {WINAPI} ( VAR lpSystemTime: SystemTime ): BOOL;
-	(** The SetThreadAffinityMask function sets a processor affinity mask for the specified thread. *)
-	SetThreadAffinityMask-: PROCEDURE {WINAPI} ( hThread: HANDLE; dwThreadAffinityMask: DWORD): LONGINT;
-	(** The SetThreadContext function sets the context in the specified thread. *)
-	SetThreadContext-: PROCEDURE {WINAPI} ( hThread: HANDLE;
-																			  VAR lpContext: Context ): BOOL;
-	(** The SetThreadPriority function sets the priority value for the specified thread. *)
-	SetThreadPriority-: PROCEDURE {WINAPI} ( hThread: HANDLE;
-																			 nPriority: LONGINT ): BOOL;
-	(** The SetupComm function initializes the communications parameters for a specified communications device. *)
-	SetupComm-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-																    dwInQueue, dwOutQueue: LONGINT ): BOOL;
-	(** The Sleep function suspends the execution of the current thread for a specified interval. *)
-	Sleep-: PROCEDURE {WINAPI} ( dwMilliseconds: LONGINT );
-	(** The SuspendThread function suspends the specified thread. *)
-	SuspendThread-: PROCEDURE {WINAPI} ( hThread: HANDLE ): LONGINT;
-	(** The SuspendThread function suspends the specified thread. *)
-	Wow64SuspendThread-: PROCEDURE {WINAPI} ( hThread: HANDLE ): LONGINT;
-	(** The SystemTimeToFileTime function converts a system time to a file time. *)
-	SystemTimeToFileTime-: PROCEDURE {WINAPI} ( VAR lpSystemTime: SystemTime;
-																					   VAR lpFileTime: FileTime ): BOOL;
-	(** The TerminateThread function terminates a thread. *)
-	TerminateThread-: PROCEDURE {WINAPI} ( hThread: HANDLE;
-																			 dwExitCode: LONGINT ): BOOL;
-	TlsAlloc-: PROCEDURE {WINAPI} ( ): LONGINT;
-	TlsFree-: PROCEDURE {WINAPI} ( dwTlsIndex: LONGINT ): BOOL;
-	TlsGetValue-: PROCEDURE {WINAPI} ( dwTlsIndex: LONGINT ): LONGINT;
-	TlsSetValue-: PROCEDURE {WINAPI} ( dwTlsIndex, lpTlsValue: LONGINT ): BOOL;
-	(** The TryEnterCriticalSection function attempts to enter a critical section without blocking. *)
-	TryEnterCriticalSection-: PROCEDURE {WINAPI} ( VAR lpCriticalSection: CriticalSection ): BOOL;
-	(** The VirtualAlloc function reserves or commits a region of pages in the virtual address space of the calling process. *)
-	VirtualAlloc-: PROCEDURE {WINAPI} ( lpAddress: ADDRESS;  dwSize: LONGINT;
-																    flAllocationType, flProtect: WORDSET ): ADDRESS;
-	(** The VirtualFree function releases or decommits (or both) a region of pages within the virtual address space of the
-			calling process. *)
-	VirtualFree-: PROCEDURE {WINAPI} ( lpAddress: ADDRESS;  dwSize: LONGINT;
-																  dwFreeType: WORDSET ): BOOL;
-	(** The WaitForSingleObject function returns when one of the following occurs:
-			The specified object is in the signaled state.
-			The time-out interval elapses. *)
-	WaitForSingleObject-: PROCEDURE {WINAPI} ( hHandle: HANDLE;
-																				   dwMilliseconds: LONGINT ): LONGINT;
-	(** The WriteFile function writes data to a file and is designed for both synchronous and asynchronous operation. *)
-	WriteFile-: PROCEDURE {WINAPI} ( hFile: HANDLE;
-															   CONST lpBuffer: ARRAY   OF SYSTEM.BYTE;
-															   nNumberOfBytesToWrite: LONGINT;
-															   VAR lpNumberOfBytesWritten: LONGINT;
-															   VAR lpOverlapped: Overlapped ): BOOL;
-	(** Thread abort notifier, parameter is the threads id. Note this should only be used in modules which
-			can't use the exception handling mechanism provided by module Exceptions. *)
-	
-	(** Method used to write text to the Console. *)
-	OutputString*: PROCEDURE ( CONST a: ARRAY OF CHAR );
-	
-
-	(* OutputString*: OutputStringProc; *)
-	Shutdown*: PROCEDURE ( code: LONGINT );
-
-	(** Wrapper for getProcAddress. *)
-	PROCEDURE GetProcAddress*( hModule: HMODULE; CONST procName: ARRAY OF CHAR; VAR adr: ADDRESS );
-	BEGIN
-		adr := getProcAddress( hModule, procName )
-	END GetProcAddress;
-
-(** Copy a zero-terminated string from address lpString. *)
-	PROCEDURE CopyString*( lpString: LPSTR;  VAR str: ARRAY OF CHAR );
-	VAR i: LONGINT;  ch: CHAR;
-	BEGIN
-		i := 0;
-		IF lpString # NULL THEN
-			SYSTEM.GET( lpString, ch );
-			WHILE ch # 0X DO
-				str[i] := ch;  INC( i );  INC( lpString );  SYSTEM.GET( lpString, ch )
-			END
-		END;
-		str[i] := 0X
-	END CopyString;
-
-	PROCEDURE OutputDebugString*( CONST str: ARRAY OF CHAR );
-	BEGIN
-		outputDebugString( str );
-	END OutputDebugString;
-
-	PROCEDURE NoOutputString(CONST str: ARRAY OF CHAR);
-	BEGIN
-	END NoOutputString;
-
-	PROCEDURE SendToDebugger*(CONST str: ARRAY OF CHAR;  x: LONGINT );
-	VAR s: ARRAY 16 OF CHAR;
-		d, i: LONGINT;
-	BEGIN
-		outputDebugString( str );  s[8] := 0X;
-		FOR i := 7 TO 0 BY -1 DO
-			d := x MOD 16;
-			IF d < 10 THEN s[i] := CHR( d + ORD( "0" ) ) ELSE s[i] := CHR( d - 10 + ORD( "A" ) ) END;
-			x := x DIV 16
-		END;
-		outputDebugString( s );  s[0] := 0AX;  s[1] := 0X;  outputDebugString( s )
-	END SendToDebugger;
-
-	PROCEDURE ShutdownP(l: LONGINT);
-	BEGIN
-		outputDebugString("Kernel32.Shutdown");
-		ExitProcess(l);
-	END ShutdownP;
-	
-	PROCEDURE Init*;
-	VAR mod: HMODULE;
-	BEGIN
-		Shutdown := ShutdownP;
-		mod := LoadLibrary("Kernel32.DLL");
-		GetProcAddress(mod, "AllocConsole",SYSTEM.VAL(ADDRESS,AllocConsole));
-		GetProcAddress(mod, "AttachConsole",SYSTEM.VAL(ADDRESS,AttachConsole));
-		GetProcAddress(mod, "Beep",SYSTEM.VAL(ADDRESS,Beep));
-		GetProcAddress(mod, "CancelIoEx",SYSTEM.VAL(ADDRESS,CancelIoEx));
-		GetProcAddress(mod, "ClearCommBreak",SYSTEM.VAL(ADDRESS,ClearCommBreak));
-		GetProcAddress(mod, "ClearCommError",SYSTEM.VAL(ADDRESS,ClearCommError));
-		GetProcAddress(mod, "CloseHandle",SYSTEM.VAL(ADDRESS,CloseHandle));
-		GetProcAddress(mod, "CopyFileA",SYSTEM.VAL(ADDRESS,CopyFile));
-		GetProcAddress(mod, "CreateDirectoryA",SYSTEM.VAL(ADDRESS,CreateDirectory));
-		GetProcAddress(mod, "CreateEventA",SYSTEM.VAL(ADDRESS,CreateEvent));
-		GetProcAddress(mod, "CreateFileA",SYSTEM.VAL(ADDRESS,CreateFile));
-		GetProcAddress(mod, "CreateProcessA",SYSTEM.VAL(ADDRESS,CreateProcess));
-		GetProcAddress(mod, "CreateSemaphoreA",SYSTEM.VAL(ADDRESS,CreateSemaphore));
-		GetProcAddress(mod, "CreateThread",SYSTEM.VAL(ADDRESS,CreateThread));
-		GetProcAddress(mod, "DeleteCriticalSection",SYSTEM.VAL(ADDRESS,DeleteCriticalSection));
-		GetProcAddress(mod, "DeleteFileA",SYSTEM.VAL(ADDRESS,DeleteFile));
-		GetProcAddress(mod, "DisableThreadLibraryCalls",SYSTEM.VAL(ADDRESS,DisableThreadLibraryCalls));
-		GetProcAddress(mod, "DuplicateHandle",SYSTEM.VAL(ADDRESS,DuplicateHandle));
-		GetProcAddress(mod, "EnterCriticalSection",SYSTEM.VAL(ADDRESS,EnterCriticalSection));
-		GetProcAddress(mod, "EscapeCommFunction",SYSTEM.VAL(ADDRESS,EscapeCommFunction));
-		GetProcAddress(mod, "ExitProcess",SYSTEM.VAL(ADDRESS,ExitProcess));
-		GetProcAddress(mod, "ExitThread",SYSTEM.VAL(ADDRESS,ExitThread));
-		GetProcAddress(mod, "FindClose",SYSTEM.VAL(ADDRESS,FindClose));
-		GetProcAddress(mod, "FileTimeToLocalFileTime",SYSTEM.VAL(ADDRESS,FileTimeToLocalFileTime));
-		GetProcAddress(mod, "FileTimeToSystemTime",SYSTEM.VAL(ADDRESS,FileTimeToSystemTime));
-		GetProcAddress(mod, "FindFirstFileA",SYSTEM.VAL(ADDRESS,FindFirstFile));
-		GetProcAddress(mod, "FindNextFileA",SYSTEM.VAL(ADDRESS,FindNextFile));
-		GetProcAddress(mod, "FlushFileBuffers",SYSTEM.VAL(ADDRESS,FlushFileBuffers));
-		GetProcAddress(mod, "FreeConsole",SYSTEM.VAL(ADDRESS,FreeConsole));
-		GetProcAddress(mod, "FreeLibrary",SYSTEM.VAL(ADDRESS,FreeLibrary));
-		GetProcAddress(mod, "GetCommandLineA",SYSTEM.VAL(ADDRESS,GetCommandLine));
-		GetProcAddress(mod, "GetCommModemStatus",SYSTEM.VAL(ADDRESS,GetCommModemStatus));
-		GetProcAddress(mod, "GetCommState",SYSTEM.VAL(ADDRESS,GetCommState));
-		GetProcAddress(mod, "GetComputerNameA",SYSTEM.VAL(ADDRESS,GetComputerName));
-		GetProcAddress(mod, "GetCurrentDirectoryA",SYSTEM.VAL(ADDRESS,GetCurrentDirectory));
-		GetProcAddress(mod, "GetCurrentProcess",SYSTEM.VAL(ADDRESS,GetCurrentProcess));
-		GetProcAddress(mod, "GetCurrentProcessId",SYSTEM.VAL(ADDRESS,GetCurrentProcessId));
-		GetProcAddress(mod, "GetCurrentThread",SYSTEM.VAL(ADDRESS,GetCurrentThread));
-		GetProcAddress(mod, "GetCurrentThreadId",SYSTEM.VAL(ADDRESS,GetCurrentThreadId));
-		GetProcAddress(mod, "GetDiskFreeSpaceA",SYSTEM.VAL(ADDRESS,GetDiskFreeSpace));
-		GetProcAddress(mod, "GetDriveTypeA",SYSTEM.VAL(ADDRESS,GetDriveType));
-		GetProcAddress(mod, "GetExitCodeProcess",SYSTEM.VAL(ADDRESS,GetExitCodeProcess));
-		GetProcAddress(mod, "GetFileAttributesA",SYSTEM.VAL(ADDRESS,GetFileAttributes));
-		GetProcAddress(mod, "GetFileSize",SYSTEM.VAL(ADDRESS,GetFileSize));
-		GetProcAddress(mod, "GetFileSizeEx",SYSTEM.VAL(ADDRESS,GetFileSizeEx));
-		GetProcAddress(mod, "GetFileTime",SYSTEM.VAL(ADDRESS,GetFileTime));
-		GetProcAddress(mod, "GetFullPathNameA",SYSTEM.VAL(ADDRESS,GetFullPathName));
-		GetProcAddress(mod, "GetLastError",SYSTEM.VAL(ADDRESS,GetLastError));
-		GetProcAddress(mod, "GetLocalTime",SYSTEM.VAL(ADDRESS,GetLocalTime));
-		GetProcAddress(mod, "GetLogicalDriveStringsA",SYSTEM.VAL(ADDRESS,GetLogicalDriveStrings));
-		GetProcAddress(mod, "GetLogicalDrives",SYSTEM.VAL(ADDRESS,GetLogicalDrives));
-		GetProcAddress(mod, "GetModuleFileNameA",SYSTEM.VAL(ADDRESS,GetModuleFileName));
-		GetProcAddress(mod, "GetModuleHandleA",SYSTEM.VAL(ADDRESS,GetModuleHandle));
-		GetProcAddress(mod, "GetOverlappedResult",SYSTEM.VAL(ADDRESS,GetOverlappedResult));
-		GetProcAddress(mod, "GetPrivateProfileStringA",SYSTEM.VAL(ADDRESS,GetPrivateProfileString));
-		(* must be done by linker: GetProcAddress(mod, "GetProcAddress",SYSTEM.VAL(ADDRESS,getProcAddress)); *)
-		GetProcAddress(mod, "GetProcessAffinityMask",SYSTEM.VAL(ADDRESS,GetProcessAffinityMask));
-		GetProcAddress(mod, "GetProcessHeap",SYSTEM.VAL(ADDRESS,GetProcessHeap));
-		GetProcAddress(mod, "GetProcessTimes", SYSTEM.VAL(ADDRESS, GetProcessTimes));
-		GetProcAddress(mod, "GetStartupInfoA",SYSTEM.VAL(ADDRESS,GetStartupInfo));
-		GetProcAddress(mod, "GetStdHandle",SYSTEM.VAL(ADDRESS,GetStdHandle));
-		GetProcAddress(mod, "GetSystemInfo",SYSTEM.VAL(ADDRESS,GetSystemInfo));
-		GetProcAddress(mod, "GetSystemTime",SYSTEM.VAL(ADDRESS,GetSystemTime));
-		GetProcAddress(mod, "GetTempFileNameA",SYSTEM.VAL(ADDRESS,GetTempFileName));
-		GetProcAddress(mod, "GetTempPathA",SYSTEM.VAL(ADDRESS,GetTempPath));
-		GetProcAddress(mod, "GetThreadContext",SYSTEM.VAL(ADDRESS,GetThreadContext));
-		GetProcAddress(mod, "Wow64GetThreadContext",SYSTEM.VAL(ADDRESS,Wow64GetThreadContext));
-		GetProcAddress(mod, "GetThreadPriority",SYSTEM.VAL(ADDRESS,GetThreadPriority));
-		GetProcAddress(mod, "GetThreadTimes",SYSTEM.VAL(ADDRESS,GetThreadTimes));
-		GetProcAddress(mod, "GetTickCount",SYSTEM.VAL(ADDRESS,GetTickCount));
-		GetProcAddress(mod, "GetWindowsDirectoryA",SYSTEM.VAL(ADDRESS,GetWindowsDirectory));
-		GetProcAddress(mod, "GetTimeZoneInformation",SYSTEM.VAL(ADDRESS,GetTimeZoneInformation));
-		GetProcAddress(mod, "GetVersion",SYSTEM.VAL(ADDRESS,GetVersion));
-		GetProcAddress(mod, "GetVersionExA",SYSTEM.VAL(ADDRESS,GetVersionEx));
-		GetProcAddress(mod, "GetVolumeInformationA",SYSTEM.VAL(ADDRESS,GetVolumeInformation));
-		GetProcAddress(mod, "GlobalAddAtomA",SYSTEM.VAL(ADDRESS,GlobalAddAtom));
-		GetProcAddress(mod, "GlobalAlloc",SYSTEM.VAL(ADDRESS,GlobalAlloc));
-		GetProcAddress(mod, "GlobalDeleteAtom",SYSTEM.VAL(ADDRESS,GlobalDeleteAtom));
-		GetProcAddress(mod, "GlobalLock",SYSTEM.VAL(ADDRESS,GlobalLock));
-		GetProcAddress(mod, "GlobalReAlloc",SYSTEM.VAL(ADDRESS,GlobalReAlloc));
-		GetProcAddress(mod, "GlobalSize",SYSTEM.VAL(ADDRESS,GlobalSize));
-		GetProcAddress(mod, "GlobalUnlock",SYSTEM.VAL(ADDRESS,GlobalUnlock));
-		GetProcAddress(mod, "HeapAlloc",SYSTEM.VAL(ADDRESS,HeapAlloc));
-		GetProcAddress(mod, "HeapFree",SYSTEM.VAL(ADDRESS,HeapFree));
-		GetProcAddress(mod, "InitializeCriticalSection",SYSTEM.VAL(ADDRESS,InitializeCriticalSection));
-		GetProcAddress(mod, "InterlockedDecrement",SYSTEM.VAL(ADDRESS,InterlockedDecrement));
-		GetProcAddress(mod, "InterlockedIncrement",SYSTEM.VAL(ADDRESS,InterlockedIncrement));
-		GetProcAddress(mod, "IsDebuggerPresent",SYSTEM.VAL(ADDRESS,IsDebuggerPresent));
-		GetProcAddress(mod, "LeaveCriticalSection",SYSTEM.VAL(ADDRESS,LeaveCriticalSection));
-		(* must be done by linker: GetProcAddress(mod, "LoadLibraryA",SYSTEM.VAL(ADDRESS,LoadLibrary)); *)
-		GetProcAddress(mod, "LocalFileTimeToFileTime",SYSTEM.VAL(ADDRESS,LocalFileTimeToFileTime));
-		GetProcAddress(mod, "MoveFileExA",SYSTEM.VAL(ADDRESS,MoveFileEx));
-		GetProcAddress(mod, "OutputDebugStringA",SYSTEM.VAL(ADDRESS,outputDebugString));
-		GetProcAddress(mod, "PurgeComm",SYSTEM.VAL(ADDRESS,PurgeComm));
-		GetProcAddress(mod, "QueryDosDeviceA",SYSTEM.VAL(ADDRESS,QueryDosDevice));
-		GetProcAddress(mod, "QueryPerformanceCounter",SYSTEM.VAL(ADDRESS,QueryPerformanceCounter));
-		GetProcAddress(mod, "QueryPerformanceFrequency",SYSTEM.VAL(ADDRESS,QueryPerformanceFrequency));
-		GetProcAddress(mod, "QueryThreadCycleTime", SYSTEM.VAL(ADDRESS, QueryThreadCycleTime));
-		GetProcAddress(mod, "ReadFile",SYSTEM.VAL(ADDRESS,ReadFile));
-		GetProcAddress(mod, "ReadProcessMemory",SYSTEM.VAL(ADDRESS,ReadProcessMemory));
-		GetProcAddress(mod, "ReleaseSemaphore",SYSTEM.VAL(ADDRESS,ReleaseSemaphore));
-		GetProcAddress(mod, "RemoveDirectoryA",SYSTEM.VAL(ADDRESS,RemoveDirectory));
-		GetProcAddress(mod, "ResetEvent",SYSTEM.VAL(ADDRESS,ResetEvent));
-		GetProcAddress(mod, "ResumeThread",SYSTEM.VAL(ADDRESS,ResumeThread));
-		GetProcAddress(mod, "SearchPathA",SYSTEM.VAL(ADDRESS,SearchPath));
-		GetProcAddress(mod, "SetCommBreak",SYSTEM.VAL(ADDRESS,SetCommBreak));
-		GetProcAddress(mod, "SetCommMask",SYSTEM.VAL(ADDRESS,SetCommMask));
-		GetProcAddress(mod, "SetCommState",SYSTEM.VAL(ADDRESS,SetCommState));
-		GetProcAddress(mod, "SetCommTimeouts",SYSTEM.VAL(ADDRESS,SetCommTimeouts));
-		GetProcAddress(mod, "SetConsoleCursorPosition",SYSTEM.VAL(ADDRESS,SetConsoleCursorPosition));
-		GetProcAddress(mod, "SetConsoleScreenBufferSize",SYSTEM.VAL(ADDRESS,SetConsoleScreenBufferSize));
-		GetProcAddress(mod, "SetConsoleTextAttribute",SYSTEM.VAL(ADDRESS,SetConsoleTextAttribute));
-		GetProcAddress(mod, "SetConsoleTitleA",SYSTEM.VAL(ADDRESS,SetConsoleTitle));
-		GetProcAddress(mod, "SetConsoleWindowInfo",SYSTEM.VAL(ADDRESS,SetConsoleWindowInfo));
-		GetProcAddress(mod, "SetCurrentDirectoryA",SYSTEM.VAL(ADDRESS,SetCurrentDirectory));
-		GetProcAddress(mod, "SetEndOfFile",SYSTEM.VAL(ADDRESS,SetEndOfFile));
-		GetProcAddress(mod, "SetErrorMode",SYSTEM.VAL(ADDRESS,SetErrorMode));
-		GetProcAddress(mod, "SetEvent",SYSTEM.VAL(ADDRESS,SetEvent));
-		GetProcAddress(mod, "SetFileAttributesA",SYSTEM.VAL(ADDRESS,SetFileAttributes));
-		GetProcAddress(mod, "SetFilePointer",SYSTEM.VAL(ADDRESS,SetFilePointer));
-		GetProcAddress(mod, "SetFilePointerEx",SYSTEM.VAL(ADDRESS,SetFilePointerEx));
-		GetProcAddress(mod, "SetFileTime",SYSTEM.VAL(ADDRESS,SetFileTime));
-		GetProcAddress(mod, "SetLocalTime",SYSTEM.VAL(ADDRESS,SetLocalTime));
-		GetProcAddress(mod, "SetThreadAffinityMask",SYSTEM.VAL(ADDRESS,SetThreadAffinityMask));
-		GetProcAddress(mod, "SetThreadContext",SYSTEM.VAL(ADDRESS,SetThreadContext));
-		GetProcAddress(mod, "SetThreadPriority",SYSTEM.VAL(ADDRESS,SetThreadPriority));
-		GetProcAddress(mod, "SetupComm",SYSTEM.VAL(ADDRESS,SetupComm));
-		GetProcAddress(mod, "Sleep",SYSTEM.VAL(ADDRESS,Sleep));
-		GetProcAddress(mod, "SuspendThread",SYSTEM.VAL(ADDRESS,SuspendThread));
-		GetProcAddress(mod, "Wow64SuspendThread",SYSTEM.VAL(ADDRESS,Wow64SuspendThread));
-		GetProcAddress(mod, "SystemTimeToFileTime",SYSTEM.VAL(ADDRESS,SystemTimeToFileTime));
-		GetProcAddress(mod, "TerminateThread",SYSTEM.VAL(ADDRESS,TerminateThread));
-		GetProcAddress(mod, "TlsAlloc",SYSTEM.VAL(ADDRESS,TlsAlloc));
-		GetProcAddress(mod, "TlsFree",SYSTEM.VAL(ADDRESS,TlsFree));
-		GetProcAddress(mod, "TlsGetValue",SYSTEM.VAL(ADDRESS,TlsGetValue));
-		GetProcAddress(mod, "TlsSetValue",SYSTEM.VAL(ADDRESS,TlsSetValue));
-		GetProcAddress(mod, "TryEnterCriticalSection", SYSTEM.VAL(ADDRESS, TryEnterCriticalSection));
-		GetProcAddress(mod, "VirtualAlloc",SYSTEM.VAL(ADDRESS,VirtualAlloc));
-		GetProcAddress(mod, "VirtualFree",SYSTEM.VAL(ADDRESS,VirtualFree));
-		GetProcAddress(mod, "WaitForSingleObject",SYSTEM.VAL(ADDRESS,WaitForSingleObject));
-		GetProcAddress(mod, "WriteFile",SYSTEM.VAL(ADDRESS,WriteFile));
-		GetProcAddress(mod, "GlobalMemoryStatusEx",SYSTEM.VAL(ADDRESS,GlobalMemoryStatusEx));
-		isEXE := hInstance = NULL;
-		IF isEXE THEN hInstance := GetModuleHandle( NIL ) END;
-		IF IsDebuggerPresent()=True THEN
-			OutputString := OutputDebugString
-		ELSE
-			OutputString := NoOutputString
-		END;
-	END Init;
-
-
-
-		(* The following procedure is linked as the first block in the code section of a PE32 executable file 
-			It contains the import table for the two procedures Kernel32.GetProcAddress and Kernel32.LoadLibrary that
-			are patched by the PE linker. 
-			[CF. Microsoft Portable Executable and Common Object File Format Specification]
-		*)
-		PROCEDURE {NOPAF, FIXED(401000H)} EntryPoint;
-		CODE{SYSTEM.i386}
-			JMP  DWORD end;
-			DB 0
-			DB 0
-			DB 0
-
-		ImportTable:
-			DD Kernel32Import + 1000H 
-			DD 0
-			DD -1
-			DD Kernel32Name + 1000H
-			DD Kernel32Import + 1000H
-			DD 0, 0, 0, 0, 0
-		
-		Kernel32Import:
-		adrLoadLibrary:			
-			DD LoadLibraryA + 1000H
-		adrGetProcAddress:			
-			DD GetProcAddress + 1000H
-			DD 0
-			
-		Kernel32Name:
-			DB 'KERNEL32.DLL' , 0
-			
-		LoadLibraryA:			
-			DW 0
-			DB 'LoadLibraryA',0,0
-			
-		GetProcAddress:
-			DW 0
-			DB 'GetProcAddress',0
-			
-		end:
-			MOV EAX,[401000H+adrLoadLibrary]
-			MOV LoadLibrary, EAX
-			MOV EAX,[401000H+adrGetProcAddress]
-			MOV getProcAddress, EAX
-			
-		END EntryPoint;
-		
-END Kernel32.

+ 3 - 2
source/Windows.I386.Machine.Mod

@@ -74,9 +74,9 @@ TYPE
 	END;
 
 VAR
-
 	LastAddress: RECORD END;
-
+	stackBottom-: ADDRESS;
+	
 	MMXSupport*: BOOLEAN;
 	SSESupport*: BOOLEAN;
 	SSE2Support*: BOOLEAN;
@@ -585,6 +585,7 @@ END Init;
 
 	PROCEDURE {INITIAL, NOPAF} Start*;
 	BEGIN
+		stackBottom := CurrentSP();
 		Init; (* cannot allocate variables in here *)
 	END Start;
 

+ 0 - 1363
source/Windows.I386.Objects.Mod

@@ -1,1363 +0,0 @@
- (* Aos, Copyright 2001, Pieter Muller, ETH Zurich; this module ported for the windows version, fof. *)
-
-MODULE Objects;   (** AUTHOR "pjm, ejz, fof"; PURPOSE "Active object runtime support"; *)
-
-IMPORT SYSTEM, Trace, Kernel32, Machine, Modules, Heaps;
-
-CONST
-	HandleExcp = TRUE;   (* FALSE -> we asume that it is done correctly by Traps *)
-	TraceVerbose = FALSE;
-	StrongChecks = FALSE;  defaultStackSize = 0;
-	TraceOpenClose = FALSE;
-
-CONST
-	(* Process flags *)
-	Restart* = 0;   (* Restart/Destroy process on exception *)
-	PleaseHalt* = 10;   (* Process requested to Halt itself soon *)
-	Unbreakable* = 11;
-	SelfTermination* = 12;
-	Preempted* = 27;   (* Has been preempted. *)
-	Resistant* = 28;   (* Can only be destroyed by itself *)
-	PleaseStop* = 31;   (* Process requested to Terminate or Halt itself soon *)
-
-	InActive* = 26;   (* needed to prevent processes to call finalizers while in await or lock or unlock, see Kernel.GC *)
-
-	(** Process modes *)
-	Unknown* = 0; Ready* = 1; (* for compatibility with native A2 *)
-	Running* = 2; AwaitingLock* = 3; AwaitingCond* = 4; AwaitingEvent* = 5; Suspended* = 6; Terminated* = 7;
-
-	(** Process priorities *)
-	MinPriority = 0;							(* only system idle processes run at this priority level *)
-	Low* = 1; Normal* = 2; High* = 3;		(* "user" priorities *)
-	GCPriority* = 4;							(* priority of garbage collector *)
-	Realtime* = 5;							(* reserved for interrupt handling and realtime apps, these processes are not allowed to allocate memory *)
-
-	(* Process termination halt codes *)
-	halt* = 2222;
-	haltUnbreakable* = 2223;
-
-
-TYPE
-	CpuCyclesArray* = ARRAY Machine.MaxCPU OF HUGEINT;
-
-	ProtectedObject = POINTER TO RECORD END;   (* protected object (10000) *)
-
-	ProcessQueue = Heaps.ProcessQueue;
-
-	Body = PROCEDURE (self: ProtectedObject);
-	Condition = PROCEDURE (slink: ADDRESS): BOOLEAN;
-
-	EventHandler* = PROCEDURE {DELEGATE};
-	RealtimeEventHandler* = PROCEDURE {DELEGATE, REALTIME};
-
-	Timer* = POINTER TO RECORD
-		next, prev : Timer;
-		trigger: LONGINT;
-		handler: EventHandler
-	END;
-
-	RealtimeTimer* = POINTER TO RECORD
-		next, prev: RealtimeTimer;
-		trigger: LONGINT;
-		handler: RealtimeEventHandler
-	END;
-
-	Clock = OBJECT
-		VAR h: Timer;
-			ticks: LONGINT;
-			hevent: Kernel32.HANDLE;
-			res: Kernel32.BOOL;
-			mode: LONGINT;
-			process: Process;
-
-		PROCEDURE Wakeup;
-		VAR res: Kernel32.BOOL;
-		BEGIN {EXCLUSIVE}
-			res := Kernel32.SetEvent(hevent)
-		END Wakeup;
-
-		PROCEDURE Finalize(ptr: ANY);
-		VAR res: Kernel32.BOOL;
-		BEGIN
-			IF hevent # 0 THEN res := Kernel32.CloseHandle(hevent);  hevent := 0 END
-		END Finalize;
-
-		PROCEDURE &Init*;
-		VAR fn: Heaps.FinalizerNode;
-		BEGIN
-			hevent := Kernel32.CreateEvent(NIL, 0, 0, NIL);
-			ASSERT(hevent # 0);
-			NEW(fn); fn.finalizer := SELF.Finalize; Heaps.AddFinalizer(SELF, fn)
-		END Init;
-
-	BEGIN {ACTIVE, SAFE, PRIORITY(High)}
-		process := CurrentProcess();
-		mode := process.mode;
-		LOOP
-			Machine.Acquire(Machine.Objects);
-			process.mode := mode;
-			LOOP
-				h := event.next;  (* event: head of timer event queue *)
-				ticks := Kernel32.GetTickCount();
-				IF (h = event) OR (h.trigger - ticks > 0) THEN EXIT END;
-				event.next := h.next;  event.next.prev := event;   (* unlink *)
-				h.next := NIL;  h.prev := NIL;
-				Machine.Release(Machine.Objects);
-				h.handler();   (* assume handler will return promptly *)
-				Machine.Acquire(Machine.Objects)
-			END;
-			mode := process.mode;
-			process.mode := AwaitingEvent;
-			Machine.Release(Machine.Objects);
-			IF h = event THEN (* sentinel head of timer event queue: wait forever until a new event has been entered in queue *)
-				res := Kernel32.WaitForSingleObject(hevent, MAX(LONGINT));
-			ELSE
-				res := Kernel32.WaitForSingleObject(hevent, h.trigger - ticks);
-			END;
-		END
-	END Clock;
-
-TYPE
-
-	Win32Event = Kernel32.HANDLE;
-	
-	GCContext = RECORD
-		ebp: ADDRESS;
-	END;
-
-	Process* = OBJECT(Heaps.ProcessLink)
-	VAR
-		rootedNext : Process; (*  to prevent process to be GCed in WinAos *)
-		obj-: ProtectedObject;   (* associated active object *)
-		state-: Kernel32.Context;
-		condition-: Condition;   (* awaited process' condition *)
-		condFP-: ADDRESS;   (* awaited process' condition's context *)
-		mode-: LONGINT;   (* process state *)  (* only changed inside Objects lock ??? *)
-		procID-: LONGINT;   (* processor ID where running,  exported for compatibilty , useless in WinAos *)
-		waitingOn-: ProtectedObject;   (* obj this process is waiting on (for lock or condition) *)
-		id-: LONGINT;   (* unique process ID for tracing *)
-		flags*: SET;   (* process flags *)
-		priority-: LONGINT;   (* process priority *)
-
-		stackBottom: ADDRESS;
-		handle-: Kernel32.HANDLE; (* handle to corresponding Windows thread *)
-		body: Body;
-		event: Win32Event;
-		restartPC-: ADDRESS;   (** entry point of body, for SAFE exception recovery *)
-		restartSP-: ADDRESS;   (** stack level at start of body, for SAFE exception recovery *)
-
-		lastThreadTimes: HUGEINT;   (*ALEX 2005.12.12*)
-		gcContext: GCContext;
-		context: ANY; (* commands contect *)
-
-		PROCEDURE FindRoots*;   (* override, called while GC, replaces Threads.CheckStacks *)
-		VAR sp: ADDRESS; res: Kernel32.BOOL; pc, bp: ADDRESS;
-			n,adr: ADDRESS; desc {UNTRACED}: Modules.ProcedureDescPointer; p {UNTRACED}: ANY; i: SIZE;
-			context: Kernel32.Wow64Context;
-			a0,a1, obp, osb, osbp, opc, gbp: ADDRESS;
-			O: ANY; ID: LONGINT;
-			mod {UNTRACED}: Modules.Module;
-			proc {UNTRACED}: Modules.ProcedureDescPointer;
-			modName: ARRAY 128 OF CHAR;
-		BEGIN
-			O := obj; ID := id;
-			IF (handle = 0) OR (mode = Terminated) OR (mode < Ready) (* procedure Wrapper not yet started *)
-			OR (priority > High) (* stack of GC and realtime processes not traced *) THEN
-				RETURN
-			END;
-						
-			IF CurrentProcess() = SELF THEN
-				sp := Machine.CurrentSP();  bp :=Machine.CurrentBP(); pc := Machine.CurrentPC(); 
-			ELSE
-				IF mode # Suspended THEN
-					IF isWow64 THEN 
-						res := Kernel32.Wow64SuspendThread(handle);
-					ELSE
-						res := Kernel32.SuspendThread(handle);
-					END;
-					ASSERT(res # -1);
-				END;
-
-				state.ContextFlags := Kernel32.ContextControl + Kernel32.ContextInteger;
-				res := Kernel32.GetThreadContext( handle, state );
-				
-				context.ContextFlags := Kernel32.ContextControl + Kernel32.ContextInteger;
-				IF isWow64 THEN 
-					res := Kernel32.Wow64GetThreadContext( handle, context );
-				ELSE
-					res := Kernel32.GetThreadContext( handle, context );
-				END;
-				ASSERT(res # 0);
-				sp := context.SP; bp := context.BP; pc := context.PC;
-				
-				mod := Modules.ThisModuleByAdr0(pc);
-				IF mod # NIL THEN
-					COPY(mod.name, modName);
-					proc := Modules.FindProc(pc,mod.procTable);
-				END;
-				
-				obp := bp; osb := stackBottom; opc := pc;
-				osbp := state.BP;
-			END;
-			gbp := gcContext.ebp;
-			IF gbp # NIL THEN bp := gbp END;
-			
-			IF TraceProcessHook # NIL THEN
-				TraceProcessHook(SELF,pc,bp,sp,stackBottom);
-			END;
-			
-			(* stack garbage collection *)
-
-			IF Heaps.GCType= Heaps.HeuristicStackInspectionGC THEN
-				Heaps.Candidate( context.EDI );  Heaps.Candidate( context.ESI );
-				Heaps.Candidate( context.EBX ); Heaps.Candidate( context.EDX );
-				Heaps.Candidate( context.ECX ); Heaps.Candidate( context.EAX );
-				IF (stackBottom # 0) & (sp # 0) THEN
-					Heaps.RegisterCandidates( sp, stackBottom - sp );
-				END;
-			ELSIF Heaps.GCType = Heaps.MetaDataForStackGC THEN
-				IF bp < stackBottom THEN
-					WHILE (bp # Heaps.NilVal) & (bp < stackBottom)  DO (* do not test for bp >= sp: could be wrong temporarily! *)
-						SYSTEM.GET(bp, n);
-						IF ODD(n) THEN (* procedure descriptor at bp *)
-							desc := SYSTEM.VAL(Modules.ProcedureDescPointer, n-1);
-							IF desc # NIL THEN
-								a0 := ADDRESSOF(desc.offsets);
-								a1 :=  SYSTEM.VAL(ADDRESS, desc.offsets);
-								ASSERT(a0+SIZEOF(ADDRESS)=a1,54321);
-								FOR i := 0 TO LEN(desc.offsets)-1 DO
-									adr := bp + desc.offsets[i]; (* pointer at offset *)
-									SYSTEM.GET(adr, p); (* load pointer *)
-									IF p # NIL THEN
-										Heaps.Mark(p);
-									END;
-								END;
-							END;
-							SYSTEM.GET(bp + SIZEOF(ADDRESS), bp);
-						ELSE (* classical stack frame *)
-							bp := n; 
-						END;
-					END;
-					
-					ASSERT((bp = stackBottom) OR (bp=0) ,12345);
-				END; 
-			END;
-			
-			IF (CurrentProcess() # SELF) & (mode # Suspended) THEN
-				res := Kernel32.ResumeThread(handle);
-				ASSERT(res # -1);
-			END;
-
-		END FindRoots;
-		
-	END Process;
-
-TYPE
-	ExceptionHandler* = PROCEDURE(	VAR context: Kernel32.Context;
-										VAR excpRec: Kernel32.ExceptionRecord;
-										VAR handled: BOOLEAN);
-
-
-	GCStatusExt = OBJECT(Heaps.GCStatus)
-	
-	(* called from Heaps.InvokeGC, i.e. this is a hidden upcall. However, it is necessary to take the Machine.Objects lock here since writing
-		    the set of variables here must not be interrupted, i.e. atomic writing of the set of variables is absolutely necessary.  They system may hang
-		    if the lock is not taken. *)
-		PROCEDURE SetgcOngoing*(value: BOOLEAN);
-		VAR p: Heaps.ProcessLink; cur, r: Process; res: Kernel32.BOOL; num: LONGINT; time: LONGINT;
-		BEGIN (* serialize writers *)
-			IF value THEN
-				(* Low, Medium or High priority process calls this *)
-				time := Kernel32.GetTickCount();
-				Machine.Acquire(Machine.Objects);
-				Machine.Acquire(Machine.Heaps); (* to protect agains concurrent LazySweep *)
-				r := CurrentProcess();
-				num := 0;
-				p := ready.head;
-				WHILE p # NIL DO
-					cur := p(Process);
-					IF ((cur.mode = Ready) OR (cur.mode = Running)) & (cur.priority <= High) & (cur # r) THEN
-						IF isWow64 THEN 
-							res := Kernel32.Wow64SuspendThread(cur.handle);
-						ELSE
-							res := Kernel32.SuspendThread(cur.handle);
-						END;
-						ASSERT(res >= 0);
-						cur.mode := Suspended
-					ELSE INC(num);
-					END;
-					p := p.next
-				END;
-
-				Heaps.CollectGarbage(Modules.root);
-				p := ready.head;
-				WHILE (p # NIL) DO
-					cur := p(Process);
-					(* only suspended and awaiting processes of ready queue are resumed *)
-					IF cur.mode = Suspended THEN
-						res := Kernel32.ResumeThread(cur.handle);
-						ASSERT(res >= 0);
-						cur.mode := Running
-					END;
-					p := p.next
-				END;
-
-				Machine.Release(Machine.Heaps);
-				Machine.Release(Machine.Objects);
-				time := Kernel32.GetTickCount()-time;
-				IF Heaps.trace THEN Trace.String("GC Called -- duration "); Trace.Int(time,0); Trace.String(" ms."); Trace.Ln END;
-				IF finalizerCaller # NIL THEN finalizerCaller.Activate() END;
-			END;
-		END SetgcOngoing;
-
-	END GCStatusExt;
-
-	FinalizedCollection* = OBJECT
-		PROCEDURE RemoveAll*(obj: ANY); (** abstract *)
-		BEGIN HALT(301) END RemoveAll;
-	END FinalizedCollection;
-
-	FinalizerNode* = POINTER TO RECORD (Heaps.FinalizerNode)
-		c*: FinalizedCollection (* base type for collection containing object *)
-	END;
-
-	FinalizerCaller = OBJECT  (* separate active object that calls finalizers *)
-	VAR n: Heaps.FinalizerNode;
-		event: Kernel32.HANDLE;
-		process: Process;
-
-		PROCEDURE &Init;
-		BEGIN
-			event := Kernel32.CreateEvent( NIL, Kernel32.False (* automatic *), Kernel32.False, NIL );
-			ASSERT(event # 0);
-		END Init;
-
-		PROCEDURE Wait;
-		VAR res: Kernel32.BOOL; mode: LONGINT;
-		BEGIN
-			mode := process.mode;
-			process.mode := AwaitingEvent;
-			res := Kernel32.WaitForSingleObject(event, Kernel32.Infinite);
-			ASSERT(res = Kernel32.WaitObject0);
-			process.mode := mode;
-		END Wait;
-
-		PROCEDURE Activate;
-		VAR res: Kernel32.BOOL;
-		BEGIN
-			res := Kernel32.SetEvent(event);
-		END Activate;
-
-	BEGIN {ACTIVE, SAFE, PRIORITY(High)}
-		process := CurrentProcess();
-		LOOP
-			Wait;
-			LOOP
-				n := Heaps.GetFinalizer();
-				IF n = NIL THEN EXIT END;
-				IF n IS FinalizerNode THEN
-					n( FinalizerNode ).c.RemoveAll( n.objStrong ) (* remove it if it is not removed yet *)
-				END;
-				IF n.finalizer # NIL THEN
-					n.finalizer( n.objStrong ) (* may acquire locks *)
-				END
-			END
-		END;
-	END FinalizerCaller;
-
-VAR
-	awc-, awl-: LONGINT;
-	oberonLoop*: ANY;   (* Oberon Loop Process temporary workaround for Threads.oberonLoop *)
-	break: ARRAY 16 OF CHAR;
-	terminateProc: PROCEDURE;
-	ready: ProcessQueue;	(* contains running processes in this implementation *)
-
-	numberOfProcessors: LONGINT; (* cached value of Machine.NumberOfProcessors() *)
-	finalizerCaller: FinalizerCaller; (* active object for finalizer process, regarded as aprt of GC *)
-
-	event: Timer; (* list of events *)
-	clock: Clock;
-	tlsIndex: LONGINT;
-	nProcs: LONGINT;
-
-	excplock: Kernel32.CriticalSection;  exceptionhandler: ExceptionHandler;
-	
-	isWow64: BOOLEAN; (* TRUE for WOW64 environment *)
-
-(* Set the current process' priority. *)
-PROCEDURE SetPriority*( priority: LONGINT );
-VAR r: Process; prio: LONGINT; res: Kernel32.BOOL;
-BEGIN
-	ASSERT((priority >= Low) & (priority <= Realtime));   (* priority in bounds *)
-	r := CurrentProcess();  r.priority := priority;
-	CASE priority OF
-	MinPriority:
-			prio := Kernel32.ThreadPriorityIdle
-	| Low:
-			prio := Kernel32.ThreadPriorityBelowNormal
-	| High:
-			prio := Kernel32.ThreadPriorityAboveNormal
-	| GCPriority, Realtime:
-			prio := Kernel32.ThreadPriorityTimeCritical
-	ELSE  (* Normal *)
-		prio := Kernel32.ThreadPriorityNormal
-	END;
-	res := Kernel32.SetThreadPriority( r.handle, prio );
-	ASSERT(r.handle # 0);
-	ASSERT(res # 0)
-END SetPriority;
-
-(** Return TRUE iff the specified protected object is locked exclusive to the current process. *)
-PROCEDURE LockedByCurrent*( obj: ANY ): BOOLEAN;
-VAR hdr {UNTRACED}: Heaps.ProtRecBlock; res: BOOLEAN;
-BEGIN
-	SYSTEM.GET(SYSTEM.VAL(ADDRESS, obj) + Heaps.HeapBlockOffset, hdr);
-	ASSERT(hdr IS Heaps.ProtRecBlock);
-	Machine.Acquire(Machine.Objects);
-	res := (hdr.lockedBy = ActiveObject());
-	Machine.Release(Machine.Objects);
-	RETURN res
-END LockedByCurrent;
-
-PROCEDURE Yield*;
-BEGIN
-	Kernel32.Sleep(0)
-END Yield;
-
-(** Return current process. (DEPRECATED, use ActiveObject) *)
-PROCEDURE CurrentProcess*( ): Process;
-BEGIN{UNCHECKED} (* makes sure that Enter and Leave are not emitted *)
-	RETURN SYSTEM.VAL(Process, Kernel32.TlsGetValue(tlsIndex));
-END CurrentProcess;
-
-PROCEDURE CurrentContext*(): ANY;
-VAR p: Process;
-BEGIN
-	p := CurrentProcess();
-	IF p # NIL THEN RETURN p.context
-	ELSE RETURN NIL
-	END;
-END CurrentContext;
-
-PROCEDURE SetContext*(context: ANY);
-VAR p: Process;
-BEGIN
-	p := CurrentProcess();
-	IF p # NIL THEN p.context := context END;
-END SetContext;
-
-(* Return stack bottom of process. For compatibility WinAos/UnixAos/NativeAos  *)
-PROCEDURE GetStackBottom*(p: Process): ADDRESS;
-BEGIN
-	RETURN p.stackBottom
-END GetStackBottom;
-
-(** Return the active object currently executing. *)
-PROCEDURE ActiveObject* (): ANY;
-VAR r: Process;
-BEGIN
-	r := SYSTEM.VAL(Process, Kernel32.TlsGetValue(tlsIndex));
-	RETURN r.obj
-END ActiveObject;
-
-(** Return the ID of the active currently executing process. *)
-PROCEDURE GetProcessID* (): LONGINT;
-VAR r: Process;
-BEGIN
-	r := SYSTEM.VAL (Process, Kernel32.TlsGetValue( tlsIndex ));
-	RETURN r.id
-END GetProcessID;
-
-(* Get a process from a queue (NIL if none). Caller must hold lock for specific queue. *)
-PROCEDURE Get(VAR queue: ProcessQueue; VAR new: Process);
-VAR t: Heaps.ProcessLink;
-BEGIN
-	t := queue.head;
-	IF t = NIL THEN  (* zero elements in queue *)
-		(* skip *)
-	ELSIF t = queue.tail THEN  (* one element in queue *)
-		queue.head := NIL; queue.tail := NIL  (* {(t.next = NIL) & (t.prev = NIL)} *)
-	ELSE  (* more than one element in queue *)
-		queue.head := t.next; t.next := NIL; queue.head.prev := NIL
-	END;
-	ASSERT((t = NIL) OR (t.next = NIL ) & (t.prev = NIL)); (* temp strong check *)
-	IF t = NIL THEN
-		new := NIL
-	ELSE
-		ASSERT(t IS Process);
-		new := t(Process)
-	END
-END Get;
-
-(* Put a process in a queue. Caller must hold lock for specific queue. *)
-(* If t was running, be careful to protect Put and the subsequent SwitchTo with the ready lock. *)
-PROCEDURE Put(VAR queue: ProcessQueue; t: Process);
-BEGIN (* {t # NIL & t.next = NIL & t.prev = NIL} *)
-	IF StrongChecks THEN
-		ASSERT((t.next = NIL) & (t.prev = NIL))
-	END;
-	t.next := NIL; t.prev := NIL; (* ug *)
-	IF queue.head = NIL THEN (* queue empty *)
-		queue.head := t
-	ELSE (* queue not empty *)
-		queue.tail.next := t; t.prev := queue.tail
-	END;
-	queue.tail := t
-END Put;
-
-(* starting address of user stack for current thread, called stack top in TIB.H *)
-PROCEDURE -StackBottom*( ): LONGINT;
-CODE {SYSTEM.i386}
-	DB	064H
-	DB	08BH
-	DB	005H
-	DB	004H
-	DB	000H
-	DB	000H
-	DB	000H
-END StackBottom;
-
-PROCEDURE {WINAPI} ExcpFrmHandler( VAR excpRec: Kernel32.ExceptionRecord; excpFrame: Kernel32.ExcpFrmPtr;
- 										VAR context: Kernel32.Context;  dispatch: LONGINT ): LONGINT;
-VAR m: Modules.Module;  eip, ebp, stack: LONGINT;  pc, handler, fp, sp: LONGINT;  handled: BOOLEAN;  t: Process;
-BEGIN
-	handled := FALSE;
-
-	Kernel32.EnterCriticalSection( excplock );
-
-	(*
-	fof: commenting this resolved a problem with multiple traps that a are catched with FINALLY statements in Windows Vista
-	in Windows XP not necessary if Kernel32.SetThreadContext is not used (better to return gracefully from this handler)
-	SetCurrent(excpFrame);
-	*)
-
-	t := CurrentProcess();
-
-	IF exceptionhandler = NIL THEN
-		Trace.StringLn ( "Objects: No exception handler installed" );
-		IF HandleExcp THEN
-
-			Trace.String( "EXCEPTION " );  Trace.Hex( excpRec.ExceptionCode, 1 );
-			Trace.String( " at " );  Trace.Hex( excpRec.ExceptionAddress, 1 );
-			Trace.Ln();  Trace.String( "EAX " );  Trace.Hex( context.EAX, 1 );
-			Trace.String( "  EBX " );  Trace.Hex( context.EBX, 1 );  Trace.Ln();
-			Trace.String( "ECX " );  Trace.Hex( context.ECX, 1 );  Trace.String( "  EDX " );
-			Trace.Hex( context.EDX, 1 );  Trace.Ln();  Trace.String( "EDI " );
-			Trace.Hex( context.EDI, 1 );  Trace.String( "  ESI " );
-			Trace.Hex( context.ESI, 1 );  Trace.Ln();  Trace.String( "EBP " );
-			Trace.Hex( context.BP, 1 );  Trace.String( "  ESP " );
-			Trace.Hex( context.SP, 1 );  Trace.Ln();  Trace.String( "EIP " );
-			Trace.Hex( context.PC, 1 );  Trace.Ln();  Trace.Ln();
-			eip := excpRec.ExceptionAddress;  ebp := context.BP;
-			IF eip = 0 THEN SYSTEM.GET( context.SP, eip ) END;
-			stack := StackBottom();
-			LOOP
-				Trace.String( "at ebp= " );  Trace.Hex( ebp, 1 );  Trace.String( "H : " );
-				m := Modules.ThisModuleByAdr( eip );
-				IF m # NIL THEN
-					Trace.String( m.name );  Trace.String( " " );
-					Trace.Hex( eip - SYSTEM.VAL( LONGINT, ADDRESSOF( m.code[0] ) ), 1 );
-				ELSE Trace.String( "EIP " );  Trace.Hex( eip, 1 )
-				END;
-				Trace.Ln();
-				IF (ebp # 0) & (ebp < stack) THEN  (* if ebp is 0 in first frame *)
-					SYSTEM.GET( ebp + 4, eip );   (* return addr from stack *)
-					SYSTEM.GET( ebp, ebp );   (* follow dynamic link *)
-				ELSE EXIT
-				END
-			END;
-			Trace.Ln();
-
-			handled := FALSE;  fp := context.BP;  sp := context.SP;
-			pc := context.PC;  handler := Modules.GetExceptionHandler( pc );
-			IF handler # -1 THEN  (* Handler in the current PAF *)
-				context.PC := handler;  handled := TRUE;
-				(*SetTrapVariable(pc, fp);  SetLastExceptionState(exc)*)
-			ELSE
-				WHILE (fp # 0) & (handler = -1) DO
-					SYSTEM.GET( fp + 4, pc );
-					pc := pc - 1;   (*  CALL instruction, machine dependant!!! *)
-					handler := Modules.GetExceptionHandler( pc );
-					sp := fp;   (* Save the old framepointer into the stack pointer *)
-					SYSTEM.GET( fp, fp ) (* Unwind PAF *)
-				END;
-				IF handler = -1 THEN handled := FALSE;
-				ELSE
-					context.PC := handler;  context.BP := fp;  context.SP := sp;
-					(* SetTrapVariable(pc, fp); SetLastExceptionState(exc);*)
-					handled := TRUE
-				END
-			END;
-		ELSE Trace.StringLn ( "Warning: FINALLY statement cannot be treated !" );
-		END
-	ELSE exceptionhandler( context, excpRec, handled );
-	END;
-	IF ~handled THEN
-		context.PC := t.restartPC;  context.SP := t.restartSP;
-		context.BP := t.stackBottom;
-	ELSIF TraceVerbose THEN Trace.StringLn ( "trying to jump to FINALLY pc..." );
-	END;
-	Kernel32.LeaveCriticalSection( excplock );
-
-	IF TraceVerbose THEN
-		Machine.Acquire (Machine.TraceOutput);
-		Trace.String( "recover process; eip=" );  Trace.Int( context.PC, 10 );
-		Trace.String( "; sp= " );  Trace.Int( context.SP, 10 );  Trace.String( "; ebp= " );
-		Trace.Int( context.BP, 10 ); Trace.Ln;
-		Machine.Release (Machine.TraceOutput);
-	END;
-
-	RETURN Kernel32.ExceptionContinueSearch; (* sets thread context and continues where specified in context *)
-END ExcpFrmHandler;
-
-(* get the currently installed execption frame *)
-(*	PROCEDURE -GetCur 64H, 8BH, 0DH, 0, 0, 0, 0;   (* MOV ECX, FS:[0] *) *)
-(* Better *)
-PROCEDURE -GetCur;
-CODE {SYSTEM.i386}
-	DB	064H, 08BH, 00DH, 000H, 000H, 000H, 000H
-END GetCur;
-
-PROCEDURE GetCurrent( ): Kernel32.ExcpFrmPtr;
-VAR cur: Kernel32.ExcpFrmPtr;
-BEGIN
-	GetCur;
-	cur := SYSTEM.VAL(Kernel32.ExcpFrmPtr,Machine.GetECX());
-	(* RETURN ECX *)
-	RETURN cur
-END GetCurrent;
-
-(* install a new exception frame *)
-(*	PROCEDURE -SetCur 64H, 0A3H, 0, 0, 0, 0;   (* MOV FS:[0], EAX *)*)
-(* Better *)
-PROCEDURE -SetCur;
-CODE {SYSTEM.i386}
-	DB	064H, 0A3H, 000H, 000H, 000H, 000H
-END SetCur;
-
-PROCEDURE SetCurrent( cur: Kernel32.ExcpFrmPtr );
-BEGIN
-	Machine.SetEAX(SYSTEM.VAL(LONGINT,cur));
-	 (* EAX := cur *)
-	SetCur
-END SetCurrent;
-
-PROCEDURE RemoveExcpFrm( VAR excpfrm: Kernel32.ExcpFrm );
-VAR this: Kernel32.ExcpFrmPtr;
-BEGIN
-	this := GetCurrent();
-	(* ASSERT ( this = ADDRESSOF( excpfrm ) );  *)
-	IF this # ADDRESSOF( excpfrm ) THEN Trace.StringLn ( "RemoveExcpFrm: Problem with excpfrm pointer" );
-	ELSE SetCurrent( excpfrm.link )
-	END;
-END RemoveExcpFrm;
-
-PROCEDURE InstallExcpFrm( VAR excpfrm: Kernel32.ExcpFrm );
-BEGIN
-	excpfrm.link := GetCurrent();  excpfrm.handler := ExcpFrmHandler;
-	SetCurrent( ADDRESSOF( excpfrm ) )
-END InstallExcpFrm;
-
-PROCEDURE InQueue( queue: ProcessQueue;  t: Process ): BOOLEAN;
-VAR p: Heaps.ProcessLink;
-BEGIN
-	p := queue.head;
-	WHILE (p # NIL ) & (p # t) DO p := p.next;  END;
-	RETURN (p = t);
-END InQueue;
-
-(* Remove a process from a queue that contains it. Caller must hold lock for specific queue. *)
-(* Not intended for frequent use. *)
-(* does not check if queue contained t ! *)
-PROCEDURE Remove( VAR queue: ProcessQueue;  t: Process );
-BEGIN
-	IF StrongChecks THEN
-		ASSERT(InQueue(queue, t));
-		ASSERT(t # NIL);
-	END;
-	IF t.prev # NIL THEN t.prev.next := t.next END;
-	IF t.next # NIL THEN t.next.prev := t.prev END;
-	IF t = queue.head THEN queue.head := t.next END;
-	IF t = queue.tail THEN queue.tail := t.prev END;
-	ASSERT((queue.head = NIL) OR (queue.head.prev = NIL) & (queue.tail.next = NIL));
-	t.prev := NIL;  t.next := NIL
-END Remove;
-
-PROCEDURE WriteType(obj: ANY);
-VAR type: LONGINT;
-BEGIN
-	IF obj = NIL THEN Trace.String(" > NIL");
-	ELSE
-		Trace.String(" > ");  SYSTEM.GET(SYSTEM.VAL(LONGINT, obj) + Heaps.TypeDescOffset, type);
-		Heaps.WriteType(type);
-	END;
-END WriteType;
-
-PROCEDURE terminate( t: Process );
-VAR hdr {UNTRACED}: Heaps.ProtRecBlock; res: Kernel32.BOOL; shutdown: BOOLEAN;
-BEGIN
-	IF t = NIL THEN RETURN END;
-	(* see Objects.TerminateThis *)
-	Machine.Acquire( Machine.Objects );
-
-	IF TraceVerbose OR TraceOpenClose THEN
-		Machine.Acquire (Machine.TraceOutput);
-		Trace.String( "Terminating process " );  Trace.Int( t.id, 1 );  WriteType( t.obj ); Trace.Ln;
-		Machine.Release (Machine.TraceOutput);
-	END;
-
-	IF (t.mode = Ready) OR (t.mode = Running) THEN Remove( ready, t );
-	ELSIF t.mode = AwaitingLock THEN
-		SYSTEM.GET(SYSTEM.VAL(ADDRESS, t.waitingOn) + Heaps.HeapBlockOffset, hdr);
-		ASSERT(hdr IS Heaps.ProtRecBlock);
-		Remove( hdr.awaitingLock, t );  Machine.Release( Machine.Objects );
-		HALT( 97 )
-	ELSIF t.mode = AwaitingCond THEN
-		SYSTEM.GET(SYSTEM.VAL(ADDRESS, t.waitingOn) + Heaps.HeapBlockOffset, hdr);
-		ASSERT(hdr IS Heaps.ProtRecBlock);
-		Remove( hdr.awaitingCond, t );  Machine.Release( Machine.Objects );
-		HALT( 98 )
-	ELSE Machine.Release( Machine.Objects );
-		HALT( 99 )
-	END;
-	t.mode := Terminated;   (* a process can also be "terminated" if the queue containing it is garbage collected *)
-	t.stackBottom := 0;  t.state.SP := 0;
-	t.restartPC := 0;
-	IF t.event # 0 THEN res := Kernel32.CloseHandle( t.event );  t.event := 0 END;
-	DEC( nProcs );  shutdown := (nProcs = 0);
-
-	Machine.Release( Machine.Objects );
-	IF shutdown THEN
-		Trace.StringLn ( " Objects: shutdown" ); Modules.Shutdown( -1 );
-		Kernel32.ExitProcess( 0 )
-	END
-END terminate;
-
-PROCEDURE {WINAPI} Wrapper( lpParameter: ANY ): LONGINT;
-VAR t: Process;  obj: ProtectedObject; res: Kernel32.BOOL; bp,sp: ADDRESS;
-	excpfrm: Kernel32.ExcpFrm;
-BEGIN
-	(* it may happen that the garbage collector runs right here and ignores this procedure.
-	    This is not a problem since lpParameter (being a reference to a process) is protected by the process lists *)
-
-	Machine.Acquire(Machine.Objects);
-
-	res := Kernel32.TlsSetValue(tlsIndex, SYSTEM.VAL(LONGINT, lpParameter));
-	t := lpParameter(Process);  obj := t.obj;
-	ASSERT(res # 0);
-	InstallExcpFrm(excpfrm);
-	SetPriority(t.priority);
-
-	bp := Machine.CurrentBP();
-	sp := Machine.CurrentSP();
-	t.restartSP := sp;
-	t.stackBottom := bp;
-	IF t.restartPC = SYSTEM.VAL(ADDRESS, terminateProc) THEN DEC(t.restartSP, SIZEOF(ADDRESS))
-	ELSE DEC(t.restartSP, 2*SIZEOF(ADDRESS))
-	END;
-	IF TraceVerbose THEN
-		Machine.Acquire(Machine.TraceOutput);
-		Trace.String("New process; restartPC= "); Trace.Int(t.restartPC, 15);
-		Trace.String("; restartSP= "); Trace.Int(t.restartSP, 15); Trace.String("; stackBottom= ");
-		Trace.Int(t.stackBottom, 15); Trace.Ln;
-		Machine.Release(Machine.TraceOutput);
-	END;
-	t.mode := Running;
-	(* now gc is enabled for this process stack *)
-	Machine.Release(Machine.Objects);
-	(* loop all processes that the GC did not see during process suspending because they were in the very moment being generated (just before the locked section) *)
-
-	(*! should not be necessary any more as GC runs immediately and without scheduling decisions
-	WHILE (gcActivity # NIL) & (gcActivity.process # NIL) & (gcActivity.process.mode = Running) DO END;
-	*)
-	t.body(obj);
-	terminate(t);
-	RemoveExcpFrm(excpfrm);
-	RETURN 0
-END Wrapper;
-
-PROCEDURE FinalizeProcess(t: ANY);
-VAR p: Process;  res: Kernel32.BOOL;
-BEGIN
-	p := t(Process);
-
-	IF TraceVerbose THEN
-		Machine.Acquire (Machine.TraceOutput);
-		Trace.String("Finalizing Process"); Trace.Int(p.id, 1);
-		WriteType(p.obj); Trace.Ln;
-		Machine.Release (Machine.TraceOutput);
-	END;
-	IF p.mode # Terminated THEN
-		IF p.mode = AwaitingLock THEN DEC(awl);
-		ELSIF p.mode = AwaitingCond THEN DEC(awc);
-		END;
-		(* no reference to the object any more *)
-		Trace.String ("Closing unreferenced process"); (*Trace.Int(p.mode,20); Trace.Int( p.id, 20 ); *) Trace.Ln; (* Trace.Ln *)
-		(* this usually happens, when an objects process waits on its own objtec and no reference exists any more. Then the object is discarded and
-		consequently the process is unreferenced (except in the object). This cannot happen when there are still other references on the object.
-		example:
-			TYPE
-			Object= OBJECT VAR active: BOOLEAN; BEGIN{ACTIVE} active := FALSE; AWAIT(active) END Object;
-			VAR o: Object;
-			BEGIN NEW(o);
-			END;
-		 *)
-	END;
-	p.mode := Terminated; (* fof for GC problem *)
-
-	IF p.handle # 0 THEN
-		res := Kernel32.CloseHandle(p.handle); p.handle := 0
-	END
-END FinalizeProcess;
-
-PROCEDURE TerminateProc;
-BEGIN
-	terminate(CurrentProcess());
-	Kernel32.ExitThread(0);
-	Kernel32.Sleep(999999);   (* wait until dependent threads terminated *)
-END TerminateProc;
-
-(* Allocate a new process associated with "obj". Must be outside lock region, because of potential GC. *)
-PROCEDURE NewProcess(body: Body; priority: LONGINT;  flags: SET; obj: ProtectedObject; VAR new: Process);
-VAR t,r: Process;  fn: Heaps.FinalizerNode;
-BEGIN
-	NEW(t);
-	t.context := CurrentContext(); (* inherit contet from parent process *)
-	t.handle := 0;
-	IF priority = 0 THEN  (* no priority specified *)
-		r := CurrentProcess();
-		t.priority := r.priority (* inherit priority of creator *)
-	ELSIF priority > 0 THEN  (* positive priority specified *)
-		t.priority := priority
-	ELSE  (* negative priority specified (only for Idle process) *)
-		t.priority := MinPriority
-	END;
-
-	NEW(fn);   (* implicit call Heaps.NewRec -> might invoke GC *)
-
-	Machine.Acquire(Machine.Objects);
-	t.next := NIL; t.prev := NIL; t.rootedNext := NIL;
-	t.waitingOn := NIL; t.flags := flags; t.obj := obj; t.mode := Unknown;
-	t.body := body; t.event := 0; fn.finalizer := FinalizeProcess;
-	Heaps.AddFinalizer(t, fn);
-	IF Restart IN flags THEN  (* restart object body *)
-		t.restartPC := SYSTEM.VAL(ADDRESS, body);
-	ELSE  (* terminate process *)
-		t.restartPC := SYSTEM.VAL(ADDRESS, terminateProc);
-	END;
-
-	t.handle := Kernel32.CreateThread(0, defaultStackSize, Wrapper, t, {}, t.id);
-
-	IF TraceVerbose OR TraceOpenClose THEN
-		Machine.Acquire(Machine.TraceOutput);
-		Trace.String("NewProcess: " ); Trace.Int(t.id, 1); WriteType(obj); Trace.Ln;
-		Machine.Release(Machine.TraceOutput);
-	END;
-
-	ASSERT(t.handle # 0);
-	new := t;
-END NewProcess;
-
-(* Create the process associated with an active object (kernel call). *)
-PROCEDURE CreateProcess*(body: Body; priority: LONGINT; flags: SET; obj: ProtectedObject);
-VAR t : Process; heapBlock {UNTRACED}: Heaps.HeapBlock;
-BEGIN
-	ASSERT(priority >= 0, 1000); ASSERT(priority <=Realtime, 1001);
-	SYSTEM.GET(SYSTEM.VAL(ADDRESS, obj) + Heaps.HeapBlockOffset, heapBlock);
-	
-	ASSERT(heapBlock IS Heaps.ProtRecBlock); (* protected object *)
-	IF Restart IN flags THEN INCL(flags, Resistant) END;   (* SAFE => Restart & Resistant *)
-	NewProcess(body, priority, flags, obj, t);  INC(nProcs);  (* acquires Machine.Objects lock *)
-	t.mode := Ready; Put(ready, t);
-	Machine.Release(Machine.Objects);
-END CreateProcess;
-
-
-(* The procedure Lock, Unlock and Await do not use header locks since it turned out that the header locks sometimes were finalized
-     too early. *)
-PROCEDURE Lock*(obj: ProtectedObject; exclusive: BOOLEAN );
-VAR hdr {UNTRACED}: Heaps.ProtRecBlock; r: Process; res: WORD;
-BEGIN  (* {called from user level} *)
-	SYSTEM.GET(SYSTEM.VAL(ADDRESS, obj) + Heaps.HeapBlockOffset, hdr);
-	IF StrongChecks THEN
-		ASSERT(hdr IS Heaps.ProtRecBlock); (* protected object *)
-		ASSERT(exclusive)	(* shared not implemented yet *)
-	END;
-	r := CurrentProcess();
-	IF StrongChecks THEN
-		ASSERT(hdr # NIL, 1001);
-		ASSERT(r # NIL, 1002);
-	END;
-	Machine.Acquire(Machine.Objects);
-	IF hdr.count = 0 THEN  (* not locked *)
-		hdr.count := -1; hdr.lockedBy := r;
-		Machine.Release(Machine.Objects)
-	ELSE  (* already locked *)
-		IF hdr.lockedBy = r THEN
-			Machine.Release(Machine.Objects);
-			HALT(2203) (* nested locks not allowed *)
-		END;
-		ASSERT(r.waitingOn = NIL); (* sanity check *)
-		Remove(ready, r);
-		IF r.event = 0 THEN
-			r.event := Kernel32.CreateEvent( NIL, Kernel32.False (* auto *), Kernel32.False, NIL );   (* auto reset event with initial state = reset *)
-			ASSERT ( r.event # 0, 1239 );
-		END;
-		r.waitingOn := obj;  r.mode := AwaitingLock;
-		Put(hdr.awaitingLock, r); INC(awl);
-		Machine.Release(Machine.Objects);
-		res := Kernel32.WaitForSingleObject(r.event, Kernel32.Infinite); (* block execution *)
-		ASSERT(res = Kernel32.WaitObject0);
-		IF StrongChecks THEN
-			ASSERT(hdr.lockedBy = r); (* at this moment only this process can own the lock and only this process can release it*)
-		END;
-	END
-END Lock;
-
-(* Find the first true condition from the queue and remove it. Assume the object is currently locked. *)
-PROCEDURE FindCondition( VAR q: ProcessQueue ): Process;
-VAR first, cand: Process;
-BEGIN
-	Get( q, first );
-	IF first.condition( first.condFP ) THEN RETURN first END;
-	Put( q, first );
-	WHILE q.head # first DO
-		Get( q, cand );
-		IF cand.condition( cand.condFP ) THEN RETURN cand END;
-		Put( q, cand )
-	END;
-	RETURN NIL
-END FindCondition;
-
-(* The procedure Lock, Unlock and Await do not use header locks since it turned out that the header locks sometimes were finalized
-     too early. *)
-PROCEDURE Unlock*( obj: ProtectedObject;  dummy: BOOLEAN );
-VAR hdr {UNTRACED}: Heaps.ProtRecBlock; t, c: Process; res: WORD;
-BEGIN
-	SYSTEM.GET(SYSTEM.VAL(ADDRESS, obj) + Heaps.HeapBlockOffset, hdr);
-	IF StrongChecks THEN
-		ASSERT(hdr IS Heaps.ProtRecBlock) (* protected object *)
-	END;
-	ASSERT(hdr.count = -1);	(* exclusive locked *)
-	Machine.Acquire(Machine.Objects);
-
-	IF hdr.awaitingCond.head # NIL THEN  (* evaluate the waiting conditions *)
-		(* we are holding the lock, so the queue can not change (to do: except in TerminateThis) *)
-		c := FindCondition(hdr.awaitingCond);   (* interrupts should be on during this call *)
-	ELSE
-		c := NIL
-	END;
-	IF c = NIL THEN  (* no true condition found, check the lock queue *)
-		Get(hdr.awaitingLock, t);
-		IF t # NIL THEN
-			hdr.lockedBy := t;
-			t.waitingOn := NIL;
-		ELSE
-			hdr.lockedBy := NIL; hdr.count := 0
-		END
-	ELSE  (* true condition found, transfer the lock *)
-		c.waitingOn := NIL; hdr.lockedBy := c;
-		t := NIL
-	END;
-	IF c # NIL THEN
-		Put(ready, c); c.mode := Running; DEC(awc);
-		res := Kernel32.SetEvent(c.event);
-		ASSERT (res # 0, 1001);
-	ELSIF t # NIL THEN
-		Put(ready, t); t.mode := Running; DEC(awl);
-		res := Kernel32.SetEvent(t.event);
-		ASSERT (res # 0, 1002);
-	END;
-	Machine.Release( Machine.Objects )
-END Unlock;
-
-(* The procedure Lock, Unlock and Await do not use header locks since it turned out that the header locks sometimes were finalized
-     too early. *)
-PROCEDURE Await*( cond: Condition;  slink: LONGINT;  obj: ProtectedObject;  flags: SET );
-VAR hdr {UNTRACED}: Heaps.ProtRecBlock; r, c, t: Process;  res: WORD;
-BEGIN
-	IF 1 IN flags THEN  (* compiler did not generate IF *)
-		IF cond(slink) THEN
-			RETURN  (* condition already true *)
-		END
-	END;
-	SYSTEM.GET(SYSTEM.VAL(ADDRESS, obj) + Heaps.HeapBlockOffset, hdr);
-	IF StrongChecks THEN
-		ASSERT(hdr IS Heaps.ProtRecBlock) (* protected object *)
-	END;
-	r := CurrentProcess();
-	Machine.Acquire(Machine.Objects);
-	IF hdr.lockedBy = r THEN  (* current process holds exclusive lock *)
-		IF StrongChecks THEN ASSERT(hdr.count = -1) END; (* exclusive locked *)
-		IF hdr.awaitingCond.head # NIL THEN	(* evaluate the waiting conditions *)
-			(* we are holding the lock, so the queue can not change (to do: except in TerminateThis) *)
-			c := FindCondition(hdr.awaitingCond)	(* interrupts should be on during this call *)
-		ELSE
-			c := NIL
-		END;
-		IF c = NIL THEN
-			Get(hdr.awaitingLock, t);
-			IF t = NIL THEN	(* none waiting - remove lock *)
-				hdr.count := 0; hdr.lockedBy := NIL;
-			ELSE	(* transfer lock to first waiting process *)
-				IF StrongChecks THEN ASSERT(t.mode = AwaitingLock) END;
-				t.waitingOn := NIL;
-				hdr.lockedBy := t;
-			END;
-		ELSE
-			c.waitingOn := NIL; hdr.lockedBy := c;
-			t := NIL;
-		END;
-	ELSE  (* no lock, or some other process may hold the lock, but that's the user's indaba (may be monotonic condition) *)
-		Machine.Release(Machine.Objects);
-		HALT( 2204 ) (* await must be exclusive region *)
-	END;
-	r.condition := cond; r.condFP := slink;
-	r.waitingOn := obj; r.mode := AwaitingCond;
-	Remove(ready, r);
-	IF r.event = 0 THEN
-		r.event := Kernel32.CreateEvent( NIL, Kernel32.False (* auto *), Kernel32.False, NIL );   (* auto-reset event with initial state = reset *)
-		ASSERT ( r.event # 0, 1239 );
-	END;
-	IF c # NIL THEN
-		DEC(awc); Put(ready, c); c.mode := Running;
-		res := Kernel32.SetEvent(c.event); (* restart execution *)
-		ASSERT(res # 0, 1002);
-	END;
-	IF t # NIL THEN
-		DEC(awl); Put(ready, t);  t.mode := Running;
-		res := Kernel32.SetEvent( t.event ); (* restart execution *)
-		ASSERT(res # 0, 1003);
-	END;
-	Put(hdr.awaitingCond, r); INC(awc);
-	Machine.Release(Machine.Objects);
-	res := Kernel32.WaitForSingleObject(r.event, Kernel32.Infinite); (* block execution *)
-	ASSERT(res = Kernel32.WaitObject0);
-	IF StrongChecks THEN
-		ASSERT(cond(slink));
-		ASSERT(hdr.lockedBy = r) (* lock held again *)
-	END
-END Await;
-
-	PROCEDURE Break*( t: Process );
-	CONST MaxTry = 50;
-	VAR mod: Modules.Module;  try: LONGINT;  retBOOL: Kernel32.BOOL;   (* Dan 09.11.05 *)
-
-		PROCEDURE SafeForBreak( mod: Modules.Module ): BOOLEAN;
-		BEGIN
-			Trace.String( "Safe for break?: " );
-			IF mod # NIL THEN
-				Trace.StringLn ( mod.name );
-				IF (mod.name = "Trace") OR (mod.name = "Machine") OR
-					(mod.name = "Heaps") OR (mod.name = "Modules") OR
-					(mod.name = "Objects") OR (mod.name = "Kernel") THEN
-					Trace.StringLn ( " - no" );  RETURN FALSE
-				ELSE Trace.StringLn ( " - yes" );  RETURN TRUE
-				END
-			ELSE Trace.StringLn ( "unknown module" );  RETURN FALSE
-			END
-		END SafeForBreak;
-
-	BEGIN
-		IF CurrentProcess() # t THEN
-			Machine.Acquire( Machine.Objects );
-			LOOP
-				IF isWow64 THEN 
-					retBOOL := Kernel32.Wow64SuspendThread(t.handle);
-				ELSE
-					retBOOL := Kernel32.SuspendThread( t.handle );
-				END;
-				t.state.ContextFlags := Kernel32.ContextControl;
-				retBOOL := Kernel32.GetThreadContext( t.handle, t.state );
-				mod := Modules.ThisModuleByAdr( t.state.PC );  Trace.String( "Objects Break at adr: " );
-				Trace.Int( t.state.PC, 5 );  Trace.Ln;
-				IF mod # NIL THEN
-					Trace.String( "In module: " );  Trace.StringLn ( mod.name );
-				END;
-				IF ~SafeForBreak( mod ) (* we do not break Kernel modules *) THEN
-					retBOOL := Kernel32.ResumeThread( t.handle );  INC( try );
-					IF try > MaxTry THEN
-						Trace.StringLn ( "Threads.Break: failed " );
-						Machine.Release( Machine.Objects );
-						RETURN
-					END
-				ELSE EXIT
-				END;
-			END;
-			(* push cont.Eip *) break[0] := 68X;
-			SYSTEM.MOVE( ADDRESSOF( t.state.PC ), ADDRESSOF( break[1] ), 4 );
-			(* push ebp *) break[5] := 055X;
-			(* mov ebp, esp *) break[6] := 08BX;  break[7] := 0ECX;
-			(* push 13 *) break[8] := 06AX;  break[9] := 0DX;
-			(* int 3 *) break[10] := 0CCX;
-			(* mov esp, ebp *) break[11] := 08BX;  break[12] := 0E5X;
-			(* pop ebp *) break[13] := 05DX;
-			(* ret *) break[14] := 0C3X;  t.state.PC := ADDRESSOF( break[0] );
-			retBOOL := Kernel32.SetThreadContext( t.handle, t.state );
-			retBOOL := Kernel32.ResumeThread( t.handle );   (*  INC( Kernel.GClevel ); *)
-
-			Machine.Release( Machine.Objects );
-		ELSE HALT( 99 )
-		END;
-
-	END Break;
-
-(* Attempt to terminate a specific process (mostly ignoring its locks). DEPRECATED *)
-PROCEDURE TerminateThis*( t: Process;  halt: BOOLEAN );
-BEGIN
-	terminate(t);
-END TerminateThis;
-
-PROCEDURE Terminate*;
-BEGIN
-	TerminateProc();
-END Terminate;
-
-PROCEDURE Init;   (* can not use NEW *)
-VAR lock: PROCEDURE(obj: ProtectedObject; exclusive: BOOLEAN);
-	unlock: PROCEDURE(obj: ProtectedObject; dummy: BOOLEAN);
-	await: PROCEDURE(cond: Condition; slink: LONGINT; obj: ProtectedObject; flags: SET);
-	create: PROCEDURE(body: Body; priority: LONGINT; flags: SET; obj: ProtectedObject);
-VAR t: Process;  fn: Heaps.FinalizerNode;  proc: Kernel32.HANDLE;
-	res: Kernel32.BOOL;
-BEGIN
-	Kernel32.InitializeCriticalSection(excplock);
-	numberOfProcessors := Machine.NumberOfProcessors();
-	lock := Lock; unlock := Unlock; await := Await; create := CreateProcess;
-
-	NEW(t);  NEW(fn);
-
-	Machine.Acquire(Machine.Objects);
-	nProcs := 1;
-	t.next := NIL;  t.prev := NIL;
-	t.waitingOn := NIL; t.flags := {}; t.obj := NIL;
-	t.mode := Unknown; t.body := NIL;
-	t.priority := Normal;
-	fn.finalizer := FinalizeProcess;
-
-	Heaps.AddFinalizer(t, fn);
-	t.handle := Kernel32.GetCurrentThread();
-	t.id := Kernel32.GetCurrentThreadId();
-	proc := Kernel32.GetCurrentProcess();
-	res := Kernel32.DuplicateHandle(proc, t.handle, proc, t.handle, {}, 0, {Kernel32.DuplicateSameAccess});
-	ASSERT(res # 0);
-	res := Kernel32.TlsSetValue(tlsIndex, SYSTEM.VAL(LONGINT, t));
-	ASSERT(res # 0);
-	t.stackBottom := StackBottom(); t.mode := Running;
-	Put( ready, t );
-	ASSERT(t.handle # 0);
-	Machine.Release(Machine.Objects);
-	InitEventHandling; (* implicit call of NewProcess! *)
-	InitGCHandling; (* do. *)
-	Heaps.gcStatus := GCStatusFactory()
-END Init;
-
-(** Set (or reset) an event handler object's timeout value. *)
-PROCEDURE SetTimeout*(t: Timer; h: EventHandler;  ms: LONGINT );
-VAR e: Timer;  trigger: LONGINT;
-BEGIN
-	ASSERT(Machine.Second= 1000); (* assume milliseconds for now *)
-	ASSERT((t # NIL) & (h # NIL));
-	ASSERT(ms >= 0);
-	Machine.Acquire(Machine.Objects);
-	trigger := Kernel32.GetTickCount() + ms;   (* ignore overflow *)
-	IF t.next # NIL THEN  (* cancel previous timeout *)
-		t.next.prev := t.prev;  t.prev.next := t.next
-	END;
-	t.trigger := trigger;  t.handler := h;
-	e := event.next;   (* performance: linear search! *)
-	WHILE (e # event) & (e.trigger - trigger <= 0) DO e := e.next END;
-	t.prev := e.prev;  e.prev := t;  t.next := e;  t.prev.next := t;
-	Machine.Release(Machine.Objects);
-	clock.Wakeup()
-END SetTimeout;
-
-(** Set (or reset) an event handler object's timeout value. Here ms is absolute *)
-PROCEDURE SetTimeoutAt*(t: Timer; h: EventHandler; ms: LONGINT);
-VAR e: Timer; trigger: LONGINT;
-BEGIN
-	ASSERT(Machine.Second= 1000);	(* assume milliseconds for now *)
-	ASSERT((t # NIL) & (h # NIL));
-	Machine.Acquire(Machine.Objects);
-	trigger := ms; (* ignore overflow *)
-	IF t.next # NIL THEN (* cancel previous timeout *)
-		t.next.prev := t.prev; t.prev.next := t.next
-	END;
-	t.trigger := trigger; t.handler := h;
-	e := event.next;	(* performance: linear search! *)
-	WHILE (e # event) & (e.trigger - trigger <= 0) DO e := e.next END;
-	t.prev := e.prev; e.prev := t; t.next := e; t.prev.next := t;
-	Machine.Release(Machine.Objects);
-	clock.Wakeup()
-END SetTimeoutAt;
-
-(** Cancel an event handler object's timeout, if any. It is possible that the timer has expired, but not yet been scheduled to run. *)
-PROCEDURE CancelTimeout*( t: Timer );
-BEGIN
-	Machine.Acquire(Machine.Objects);
-	ASSERT (t # event );
-	IF t.next # NIL THEN
-		t.next.prev := t.prev;  
-		IF t.prev#NIL THEN t.prev.next := t.next; END;
-		t.next := NIL;
-		t.prev := NIL
-	END;
-	Machine.Release(Machine.Objects);
-END CancelTimeout;
-
-PROCEDURE InitEventHandling;
-BEGIN
-	NEW(event); event.next := event; event.prev := event;  (* event: head of timer event queue, only a sentinel *)
-	NEW(clock);
-END InitEventHandling;
-
-PROCEDURE InitGCHandling;
-BEGIN
-	NEW(finalizerCaller);
-END InitGCHandling;
-
-PROCEDURE GCStatusFactory(): Heaps.GCStatus;
-VAR gcStatusExt : GCStatusExt;
-BEGIN
-	ASSERT(Heaps.gcStatus = NIL);
-	NEW(gcStatusExt);
-	RETURN gcStatusExt
-END GCStatusFactory;
-
-PROCEDURE InstallExceptionHandler*( e: ExceptionHandler );
-BEGIN
-	exceptionhandler := e;
-END InstallExceptionHandler;
-
-PROCEDURE UpdateProcessState*( p: Process );
-VAR res: Kernel32.BOOL;
-BEGIN
-	res := Kernel32.GetThreadContext( p.handle, p.state );
-	ASSERT (p.handle # 0);
-END UpdateProcessState;
-
-(*ALEX 2005.12.12 added for WMPerfMon needs*)
-
-PROCEDURE NumReady*( ): LONGINT;
-VAR n: LONGINT; p: Heaps.ProcessLink;
-BEGIN
-	n := 0;
-	Machine.Acquire( Machine.Objects );
-	p := ready.head;
-	WHILE p # NIL DO INC( n );  p := p.next END;
-	Machine.Release( Machine.Objects );
-	RETURN n
-END NumReady;
-
-(** Return number of CPU cycles consumed by the specified process. If all is TRUE,
-	return the number of cycles since the process has been created. If FALSE, return the number of cycles
-	consumed since the last time asked. *)
-PROCEDURE GetCpuCycles*(process : Process; VAR cpuCycles : CpuCyclesArray; all : BOOLEAN);
-VAR res : Kernel32.BOOL; temp : HUGEINT; 
-BEGIN
-	ASSERT(process # NIL);
-	IF (Kernel32.QueryThreadCycleTime # NIL) THEN
-		res := Kernel32.QueryThreadCycleTime(process.handle, cpuCycles[0]);
-	ELSE
-		cpuCycles[0] := Machine.GetTimer(); res := Kernel32.True;
-	END;
-
-	IF ~all & (res = Kernel32.True) THEN
-		temp := process.lastThreadTimes;
-		process.lastThreadTimes := cpuCycles[0];
-		cpuCycles[0] := cpuCycles[0] - temp;
-	END;
-END GetCpuCycles;
-
-PROCEDURE CurrentProcessTime*(): HUGEINT;
-VAR res: WORD; result: HUGEINT;
-BEGIN
-	IF (Kernel32.QueryThreadCycleTime # NIL) THEN
-		res := Kernel32.QueryThreadCycleTime(CurrentProcess().handle, result);
-	ELSE (* fallback *)
-		result := Machine.GetTimer();
-	END;
-	RETURN result;
-END CurrentProcessTime;
-
-PROCEDURE TimerFrequency*(): HUGEINT;
-BEGIN
-	RETURN 1000000000;
-END TimerFrequency;
-
-VAR GetProcedureName*: PROCEDURE (pc: ADDRESS; VAR n: ARRAY OF CHAR; VAR spc: ADDRESS);
-
-PROCEDURE LeaveA2*;
-VAR cur: Process; ebp,n: ADDRESS;
-BEGIN
-	IF clock = NIL THEN RETURN END;
-	cur := CurrentProcess();
-	IF cur # NIL THEN 
-		ebp := Machine.CurrentBP();
-		SYSTEM.GET(ebp, n);
-		IF ODD(n) THEN SYSTEM.GET(ebp + SIZEOF(ADDRESS), ebp) ELSE ebp := n END;
-		cur.gcContext.ebp := ebp;
-	END;
-END LeaveA2;
-
-PROCEDURE ReenterA2*;
-VAR cur: Process;
-BEGIN
-	IF clock = NIL THEN RETURN END;
-	cur := CurrentProcess();
-	IF cur # NIL THEN 
-		cur.gcContext.ebp := NIL;
-	END;	
-END ReenterA2;
-
-VAR
-	lpContext: Kernel32.Wow64Context;
-	TraceProcessHook*: PROCEDURE (prcoess: Process; pc, bp: ADDRESS; stacklow, stackhigh: ADDRESS);
-	
-BEGIN
-	TraceProcessHook := NIL;
-	exceptionhandler := NIL;
-	terminateProc := TerminateProc;
-	ready.head := NIL; ready.tail := NIL;
-	tlsIndex := Kernel32.TlsAlloc();
-	ASSERT ( tlsIndex # Kernel32.TLSOutOfIndexes );
-	Kernel32.SendToDebugger("Modules.root", ADDRESSOF(Modules.root));
-	
-	(* determine whether it is WOW64 environment *)
-	isWow64 := (Kernel32.Wow64GetThreadContext # NIL) & (Kernel32.Wow64GetThreadContext(Kernel32.GetCurrentThread(),lpContext) # 0); 
-	IF isWow64 THEN
-		Trace.String("Use Wow64"); Trace.Ln;
-	END;
-	Init
-END Objects.
-
-(*
-24.03.1998	pjm	Started
-06.05.1998	pjm	CreateProcess init process, page fault handler
-06.08.1998	pjm	Moved exception interrupt handling here for current process
-17.08.1998	pjm	FindRoots method
-02.10.1998	pjm	Idle process
-06.11.1998	pjm	snapshot
-25.03.1999	pjm	Scope removed
-28.05.1999	pjm	EventHandler object
-01.06.1999	pjm	Fixed InterruptProcess lock error
-16.06.1999	pjm	Flat IRQ priority model to avoid GC deadlock
-23.06.1999	pjm	Flat IRQ priority experiment failed, rather do STI in FieldIRQ to avoid GC deadlock
-29.06.1999	pjm	Timeout in EventHandler object
-13.01.2000	pjm	Overed (Interrupt Objects, Event Handlers, Process ID, Process state, Process mode, Process stack, Await)
-17.10.2000	pjm	Priorities
-22.10.2003	mib	SSE2 extension
-24.10.2003	phk	Priority inversion / cycle counters
-
-Stack invariant for GC:
-o if process is running, the processor registers contain its state
-o if process is not running, at least state.ESP is valid, and between stack.adr and stack.high (for GC)
-
-o when releasing the Ready lock, make sure the process state is up to date
-*)
-
-System.ShowStacks ~
-
-Heaps.SetMetaData 
-
-Linker.Link --fileFormat=PE32 --fileName=A2GC.exe --extension=GofW --displacement=401000H Builtins Trace Kernel32 Machine Heaps Modules Objects Kernel KernelLog Streams Commands FIles WinFS Clock Dates Reals Strings Diagnostics BitSets StringPool ObjectFile GenericLinker Reflection  Loader  BootConsole ~

+ 55 - 10
source/Windows.AMD64.Kernel32.Mod → source/Windows.Kernel32.Mod

@@ -135,7 +135,7 @@ CONST
 
 	(** EscapeCommFunction *)
 	SETXOFF* = 1;  SETXON* = 2;  SETRTS* = 3;  CLRRTS* = 4;  SETDTR* = 5;
-	CLRDTR* = 6;  REDWORDDEV* = 7;  SETBREAK* = 8;  CLRBREAK* = 9;
+	CLRDTR* = 6;  RESETDEV* = 7;  SETBREAK* = 8;  CLRBREAK* = 9;
 
 	(** PurgeComm *)
 	PurgeTXAbort* = 0;  PurgeRXAbort* = 1;  PurgeTXClear* = 2;
@@ -211,7 +211,7 @@ TYPE
 	END;
 
 	ContextPtr*= POINTER {UNSAFE,UNTRACED} TO Context;
-	(* 32 bit
+	#IF WIN32 THEN
 	Context* = RECORD
 		ContextFlags*: WORDSET;
 		DR0*, DR1*, DR2*, DR3*, DR6*, DR7*: SIZE;
@@ -220,8 +220,7 @@ TYPE
 		EDI*, ESI*, EBX*, EDX*, ECX*, EAX*: ADDRESS;
 		BP*, PC*, CS*, FLAGS*, SP*, SS*: ADDRESS; (* whereas BP is EBP and SP is ESP *)
 	END;
-	*) 
-	
+	#ELSIF WIN64 THEN
 	Context*= RECORD
 		P1Home, P2Home, P3Home, P4Home, P5Home, P6Home: SIZE; 
 		
@@ -273,7 +272,7 @@ TYPE
 } CONTEXT, *PCONTEXT;
 	*)
 	END; 
-				
+	#END;			
 	
 	ExceptionRecordPtr* = POINTER {UNSAFE,UNTRACED} TO ExceptionRecord;
 	ExceptionRecord* = RECORD
@@ -928,7 +927,6 @@ VAR
 	PROCEDURE ShutdownP(l: LONGINT);
 	VAR i: LONGINT;
 	BEGIN
-		(* FOR i := 0 TO 0x10000000 DO END;*) 
 		OutputString("Kernel32.Shutdown");
 		ExitProcess(l);
 	END ShutdownP;
@@ -1115,7 +1113,54 @@ VAR hout: HANDLE;
 	END SetTraceConsole;
 
 
+#IF WIN32 THEN
+		(* The following procedure is linked as the first block in the code section of a PE32 executable file 
+			It contains the import table for the two procedures Kernel32.GetProcAddress and Kernel32.LoadLibrary that
+			are patched by the PE linker. 
+			[CF. Microsoft Portable Executable and Common Object File Format Specification]
+		*)
+		PROCEDURE {NOPAF, FIXED(401000H)} EntryPoint;
+		CODE{SYSTEM.i386}
+			JMP  DWORD end;
+			DB 0
+			DB 0
+			DB 0
 
+		ImportTable:
+			DD Kernel32Import + 1000H 
+			DD 0
+			DD -1
+			DD Kernel32Name + 1000H
+			DD Kernel32Import + 1000H
+			DD 0, 0, 0, 0, 0
+		
+		Kernel32Import:
+		adrLoadLibrary:			
+			DD LoadLibraryA + 1000H
+		adrGetProcAddress:			
+			DD GetProcAddress + 1000H
+			DD 0
+			
+		Kernel32Name:
+			DB 'KERNEL32.DLL' , 0
+			
+		LoadLibraryA:			
+			DW 0
+			DB 'LoadLibraryA',0,0
+			
+		GetProcAddress:
+			DW 0
+			DB 'GetProcAddress',0
+			
+		end:
+			MOV EAX,[401000H+adrLoadLibrary]
+			MOV LoadLibrary, EAX
+			MOV EAX,[401000H+adrGetProcAddress]
+			MOV getProcAddress, EAX
+			
+		END EntryPoint;
+		
+#ELSIF WIN64 THEN
 		(* The following procedure is linked as the first block in the code section of a PE32 executable file 
 			It contains the import table for the two procedures Kernel32.GetProcAddress and Kernel32.LoadLibrary that
 			are patched by the PE linker. 
@@ -1163,8 +1208,8 @@ VAR hout: HANDLE;
 			MOV RAX,[401000H+adrGetProcAddress]
 			MOV getProcAddress, RAX
 	END EntryPoint;
-		
-(*BEGIN
-	Init;*)
-	
+#ELSE
+	UNIMPLEMENTED
+#END	
+
 END Kernel32.

+ 46 - 59
source/Windows.AMD64.Objects.Mod → source/Windows.Objects.Mod

@@ -159,8 +159,6 @@ TYPE
 			mod {UNTRACED}: Modules.Module;
 			proc {UNTRACED}: Modules.ProcedureDescPointer;
 			modName: ARRAY 128 OF CHAR;
-			mode0,mode1: LONGINT;
-			
 			contextPos: SIZE;
 		BEGIN{UNCHECKED} (* avoid winapi call indirection *)
 			O := obj; ID := id;
@@ -198,9 +196,22 @@ TYPE
 			(* stack garbage collection *)
 
 			IF Heaps.GCType= Heaps.HeuristicStackInspectionGC THEN
+			#IF WIN64 THEN
 				Heaps.Candidate( state.RDI );  Heaps.Candidate( state.RSI );
 				Heaps.Candidate( state.RBX ); Heaps.Candidate( state.RDX );
 				Heaps.Candidate( state.RCX ); Heaps.Candidate( state.RAX );
+				Heaps.Candidate( state.R9 );  Heaps.Candidate( state.R10 );
+				Heaps.Candidate( state.R11 ); Heaps.Candidate( state.R12 );
+				Heaps.Candidate( state.R13 ); Heaps.Candidate( state.R14 );
+				Heaps.Candidate( state.R15 );
+			#ELSIF WIN32 THEN
+				Heaps.Candidate( state.EDI );  Heaps.Candidate( state.ESI );
+				Heaps.Candidate( state.EBX ); Heaps.Candidate( state.EDX );
+				Heaps.Candidate( state.ECX ); Heaps.Candidate( state.EAX );
+			#ELSE
+				ASSERT(FALSE);
+			#END
+				
 				IF (stackBottom # 0) & (sp # 0) THEN
 					Heaps.RegisterCandidates( sp, stackBottom - sp );
 				END;
@@ -528,25 +539,36 @@ BEGIN
 
 			Trace.String( "EXCEPTION " );  Trace.Address(exceptionPointers.exception.ExceptionCode);
 			Trace.String( " at " );  Trace.Address(exceptionPointers.exception.ExceptionAddress);
-			Trace.Ln();  Trace.String( "RAX " );  Trace.Address(exceptionPointers.context.RAX);
-			Trace.String( "  RBX " );  Trace.Address(exceptionPointers.context.RBX);  Trace.Ln();
-			Trace.String( "RCX " );  Trace.Address(exceptionPointers.context.RCX);  Trace.String( "  RDX " );
-			Trace.Address(exceptionPointers.context.RDX);  Trace.Ln();  Trace.String( "RDI " );
-			Trace.Address(exceptionPointers.context.RDI);  Trace.String( "  RSI " );
-			Trace.Address(exceptionPointers.context.RSI);  Trace.Ln(); 
-			
-			Trace.String( "R8 " ); Trace.Address(exceptionPointers.context.R8);
-			Trace.String( " R9 " ); Trace.Address(exceptionPointers.context.R9);  Trace.Ln();  
-			Trace.String( "R10 " ); Trace.Address(exceptionPointers.context.R10);
-			Trace.String( " R11 " ); Trace.Address(exceptionPointers.context.R11);  Trace.Ln();  
-			Trace.String( "R12 " ); Trace.Address(exceptionPointers.context.R12);
-			Trace.String( " R13 " ); Trace.Address(exceptionPointers.context.R13);  Trace.Ln();  
-			Trace.String( "R14 " ); Trace.Address(exceptionPointers.context.R14);
-			Trace.String( " R15 " ); Trace.Address(exceptionPointers.context.R15);  Trace.Ln();  
-			Trace.Ln; 
+			#IF WIN64 THEN
+				Trace.Ln();  Trace.String( "RAX " );  Trace.Address(exceptionPointers.context.RAX);
+				Trace.String( "  RBX " );  Trace.Address(exceptionPointers.context.RBX);  Trace.Ln();
+				Trace.String( "RCX " );  Trace.Address(exceptionPointers.context.RCX);  Trace.String( "  RDX " );
+				Trace.Address(exceptionPointers.context.RDX);  Trace.Ln();  Trace.String( "RDI " );
+				Trace.Address(exceptionPointers.context.RDI);  Trace.String( "  RSI " );
+				Trace.Address(exceptionPointers.context.RSI);  Trace.Ln(); 
+				
+				Trace.String( "R8 " ); Trace.Address(exceptionPointers.context.R8);
+				Trace.String( " R9 " ); Trace.Address(exceptionPointers.context.R9);  Trace.Ln();  
+				Trace.String( "R10 " ); Trace.Address(exceptionPointers.context.R10);
+				Trace.String( " R11 " ); Trace.Address(exceptionPointers.context.R11);  Trace.Ln();  
+				Trace.String( "R12 " ); Trace.Address(exceptionPointers.context.R12);
+				Trace.String( " R13 " ); Trace.Address(exceptionPointers.context.R13);  Trace.Ln();  
+				Trace.String( "R14 " ); Trace.Address(exceptionPointers.context.R14);
+				Trace.String( " R15 " ); Trace.Address(exceptionPointers.context.R15);  Trace.Ln();  
+				Trace.Ln; 
+			#ELSIF WIN32 THEN
+				Trace.Ln();  Trace.String( "EAX " );  Trace.Hex( exceptionPointers.context.EAX, 1 );
+				Trace.String( "  EBX " );  Trace.Hex( exceptionPointers.context.EBX, 1 );  Trace.Ln();
+				Trace.String( "ECX " );  Trace.Hex( exceptionPointers.context.ECX, 1 );  Trace.String( "  EDX " );
+				Trace.Hex( exceptionPointers.context.EDX, 1 );  Trace.Ln();  Trace.String( "EDI " );
+				Trace.Hex( exceptionPointers.context.EDI, 1 );  Trace.String( "  ESI " );
+				Trace.Hex( exceptionPointers.context.ESI, 1 );  Trace.Ln();  
+			#ELSE 
+				-- UNIMPLEMENTED --
+			#END
 			
-			Trace.String( "RBP " );
-			Trace.Address(exceptionPointers.context.BP);  Trace.String( "  RSP " );
+			Trace.String( "BP " );
+			Trace.Address(exceptionPointers.context.BP);  Trace.String( "  SP " );
 			Trace.Address(exceptionPointers.context.SP);  Trace.Ln();  Trace.String( "PC " );
 			Trace.Address(exceptionPointers.context.PC);  Trace.Ln();  
 			
@@ -714,7 +736,6 @@ BEGIN
 	res := Kernel32.TlsSetValue(tlsIndex, SYSTEM.VAL(LONGINT, lpParameter));
 	t := lpParameter(Process);  obj := t.obj;
 	ASSERT(res # 0);
-
 	SetPriority(t.priority);
 	bp := Machine.CurrentBP();
 	sp := Machine.CurrentSP();
@@ -1078,13 +1099,6 @@ BEGIN
 	TerminateProc();
 END Terminate;
 
-TYPE KdHelp = RECORD
-	Thread: ADDRESS;
-	ThCallBackStack,ThCallBackStore,NextCallback,FramePointer: Kernel32.DWORD;
-	KiCallUserMode, KeUserCallbackDispatcher,SystemRangeStart,KiUserExceptionDispatcher,StackBase,StackLimit: ADDRESS;
-	Reserved: ARRAY 5 OF ADDRESS;
-END; 
-
 PROCEDURE Init;   (* can not use NEW *)
 VAR t: Process;  fn: Heaps.FinalizerNode;  proc: Kernel32.HANDLE;
 	res: Kernel32.BOOL;
@@ -1260,12 +1274,14 @@ VAR GetProcedureName*: PROCEDURE (pc: ADDRESS; VAR n: ARRAY OF CHAR; VAR spc: AD
 PROCEDURE LeaveA2*;
 VAR cur: Process; ebp,n: ADDRESS;
 BEGIN
+	#IF WIN64 THEN	
 	CODE
 		PUSH RCX
 		PUSH RDX
 		PUSH R8
 		PUSH R9
 	END;
+	#END
 	IF clock = NIL THEN 
 		RETURN 
 	END;
@@ -1281,12 +1297,14 @@ BEGIN
 		IF cur.gcContext.nextPos > 255 THEN cur.gcContext.nextPos := 255 END;
 		(* IF (cur.gcContext.nextPos > 4) THEN cur.gcContext.nextPos := 2 END;*)
 	END;
+	#IF WIN64 THEN
 	CODE
 		POP R9
 		POP R8
 		POP RDX
 		POP RCX
 	END;
+	#END
 END LeaveA2;
 
 PROCEDURE ReenterA2*;
@@ -1317,34 +1335,3 @@ BEGIN
 	
 	Init;
 END Objects.
-
-(*
-24.03.1998	pjm	Started
-06.05.1998	pjm	CreateProcess init process, page fault handler
-06.08.1998	pjm	Moved exception interrupt handling here for current process
-17.08.1998	pjm	FindRoots method
-02.10.1998	pjm	Idle process
-06.11.1998	pjm	snapshot
-25.03.1999	pjm	Scope removed
-28.05.1999	pjm	EventHandler object
-01.06.1999	pjm	Fixed InterruptProcess lock error
-16.06.1999	pjm	Flat IRQ priority model to avoid GC deadlock
-23.06.1999	pjm	Flat IRQ priority experiment failed, rather do STI in FieldIRQ to avoid GC deadlock
-29.06.1999	pjm	Timeout in EventHandler object
-13.01.2000	pjm	Overed (Interrupt Objects, Event Handlers, Process ID, Process state, Process mode, Process stack, Await)
-17.10.2000	pjm	Priorities
-22.10.2003	mib	SSE2 extension
-24.10.2003	phk	Priority inversion / cycle counters
-
-Stack invariant for GC:
-o if process is running, the processor registers contain its state
-o if process is not running, at least state.ESP is valid, and between stack.adr and stack.high (for GC)
-
-o when releasing the Ready lock, make sure the process state is up to date
-*)
-
-System.ShowStacks ~
-
-Heaps.SetMetaData 
-
-Linker.Link --fileFormat=PE32 --fileName=A2GC.exe --extension=GofW --displacement=401000H Builtins Trace Kernel32 Machine Heaps Modules Objects Kernel KernelLog Streams Commands FIles WinFS Clock Dates Reals Strings Diagnostics BitSets StringPool ObjectFile GenericLinker Reflection  Loader  BootConsole ~