Bläddra i källkod

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 år sedan
förälder
incheckning
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 }
 	SOLARIS32 { Unix.Glue.Mod Solaris.I386.Unix.Mod }
 	SOLARIS64 { Unix.Glue.Mod Solaris.AMD64.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 }
 	BIOS32 { BIOS.I386.Machine.Mod }
 	BIOS64 { BIOS.AMD64.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 }
 	COOP { GarbageCollector.Mod }
 
 
 	BIOS { BIOS.Objects.Mod Kernel.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 }
 	UNIX { Unix.Objects.Mod Unix.Kernel.Mod }
 	COOP { Coop.Objects.Mod Coop.Kernel.Mod }
 	COOP { Coop.Objects.Mod Coop.Kernel.Mod }
 END
 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;
 	END;
 
 
 VAR
 VAR
-
 	LastAddress: RECORD END;
 	LastAddress: RECORD END;
-
+	stackBottom-: ADDRESS;
+	
 	MMXSupport*: BOOLEAN;
 	MMXSupport*: BOOLEAN;
 	SSESupport*: BOOLEAN;
 	SSESupport*: BOOLEAN;
 	SSE2Support*: BOOLEAN;
 	SSE2Support*: BOOLEAN;
@@ -585,6 +585,7 @@ END Init;
 
 
 	PROCEDURE {INITIAL, NOPAF} Start*;
 	PROCEDURE {INITIAL, NOPAF} Start*;
 	BEGIN
 	BEGIN
+		stackBottom := CurrentSP();
 		Init; (* cannot allocate variables in here *)
 		Init; (* cannot allocate variables in here *)
 	END Start;
 	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 *)
 	(** EscapeCommFunction *)
 	SETXOFF* = 1;  SETXON* = 2;  SETRTS* = 3;  CLRRTS* = 4;  SETDTR* = 5;
 	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 *)
 	(** PurgeComm *)
 	PurgeTXAbort* = 0;  PurgeRXAbort* = 1;  PurgeTXClear* = 2;
 	PurgeTXAbort* = 0;  PurgeRXAbort* = 1;  PurgeTXClear* = 2;
@@ -211,7 +211,7 @@ TYPE
 	END;
 	END;
 
 
 	ContextPtr*= POINTER {UNSAFE,UNTRACED} TO Context;
 	ContextPtr*= POINTER {UNSAFE,UNTRACED} TO Context;
-	(* 32 bit
+	#IF WIN32 THEN
 	Context* = RECORD
 	Context* = RECORD
 		ContextFlags*: WORDSET;
 		ContextFlags*: WORDSET;
 		DR0*, DR1*, DR2*, DR3*, DR6*, DR7*: SIZE;
 		DR0*, DR1*, DR2*, DR3*, DR6*, DR7*: SIZE;
@@ -220,8 +220,7 @@ TYPE
 		EDI*, ESI*, EBX*, EDX*, ECX*, EAX*: ADDRESS;
 		EDI*, ESI*, EBX*, EDX*, ECX*, EAX*: ADDRESS;
 		BP*, PC*, CS*, FLAGS*, SP*, SS*: ADDRESS; (* whereas BP is EBP and SP is ESP *)
 		BP*, PC*, CS*, FLAGS*, SP*, SS*: ADDRESS; (* whereas BP is EBP and SP is ESP *)
 	END;
 	END;
-	*) 
-	
+	#ELSIF WIN64 THEN
 	Context*= RECORD
 	Context*= RECORD
 		P1Home, P2Home, P3Home, P4Home, P5Home, P6Home: SIZE; 
 		P1Home, P2Home, P3Home, P4Home, P5Home, P6Home: SIZE; 
 		
 		
@@ -273,7 +272,7 @@ TYPE
 } CONTEXT, *PCONTEXT;
 } CONTEXT, *PCONTEXT;
 	*)
 	*)
 	END; 
 	END; 
-				
+	#END;			
 	
 	
 	ExceptionRecordPtr* = POINTER {UNSAFE,UNTRACED} TO ExceptionRecord;
 	ExceptionRecordPtr* = POINTER {UNSAFE,UNTRACED} TO ExceptionRecord;
 	ExceptionRecord* = RECORD
 	ExceptionRecord* = RECORD
@@ -928,7 +927,6 @@ VAR
 	PROCEDURE ShutdownP(l: LONGINT);
 	PROCEDURE ShutdownP(l: LONGINT);
 	VAR i: LONGINT;
 	VAR i: LONGINT;
 	BEGIN
 	BEGIN
-		(* FOR i := 0 TO 0x10000000 DO END;*) 
 		OutputString("Kernel32.Shutdown");
 		OutputString("Kernel32.Shutdown");
 		ExitProcess(l);
 		ExitProcess(l);
 	END ShutdownP;
 	END ShutdownP;
@@ -1115,7 +1113,54 @@ VAR hout: HANDLE;
 	END SetTraceConsole;
 	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 
 		(* 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
 			It contains the import table for the two procedures Kernel32.GetProcAddress and Kernel32.LoadLibrary that
 			are patched by the PE linker. 
 			are patched by the PE linker. 
@@ -1163,8 +1208,8 @@ VAR hout: HANDLE;
 			MOV RAX,[401000H+adrGetProcAddress]
 			MOV RAX,[401000H+adrGetProcAddress]
 			MOV getProcAddress, RAX
 			MOV getProcAddress, RAX
 	END EntryPoint;
 	END EntryPoint;
-		
-(*BEGIN
-	Init;*)
-	
+#ELSE
+	UNIMPLEMENTED
+#END	
+
 END Kernel32.
 END Kernel32.

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

@@ -159,8 +159,6 @@ TYPE
 			mod {UNTRACED}: Modules.Module;
 			mod {UNTRACED}: Modules.Module;
 			proc {UNTRACED}: Modules.ProcedureDescPointer;
 			proc {UNTRACED}: Modules.ProcedureDescPointer;
 			modName: ARRAY 128 OF CHAR;
 			modName: ARRAY 128 OF CHAR;
-			mode0,mode1: LONGINT;
-			
 			contextPos: SIZE;
 			contextPos: SIZE;
 		BEGIN{UNCHECKED} (* avoid winapi call indirection *)
 		BEGIN{UNCHECKED} (* avoid winapi call indirection *)
 			O := obj; ID := id;
 			O := obj; ID := id;
@@ -198,9 +196,22 @@ TYPE
 			(* stack garbage collection *)
 			(* stack garbage collection *)
 
 
 			IF Heaps.GCType= Heaps.HeuristicStackInspectionGC THEN
 			IF Heaps.GCType= Heaps.HeuristicStackInspectionGC THEN
+			#IF WIN64 THEN
 				Heaps.Candidate( state.RDI );  Heaps.Candidate( state.RSI );
 				Heaps.Candidate( state.RDI );  Heaps.Candidate( state.RSI );
 				Heaps.Candidate( state.RBX ); Heaps.Candidate( state.RDX );
 				Heaps.Candidate( state.RBX ); Heaps.Candidate( state.RDX );
 				Heaps.Candidate( state.RCX ); Heaps.Candidate( state.RAX );
 				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
 				IF (stackBottom # 0) & (sp # 0) THEN
 					Heaps.RegisterCandidates( sp, stackBottom - sp );
 					Heaps.RegisterCandidates( sp, stackBottom - sp );
 				END;
 				END;
@@ -528,25 +539,36 @@ BEGIN
 
 
 			Trace.String( "EXCEPTION " );  Trace.Address(exceptionPointers.exception.ExceptionCode);
 			Trace.String( "EXCEPTION " );  Trace.Address(exceptionPointers.exception.ExceptionCode);
 			Trace.String( " at " );  Trace.Address(exceptionPointers.exception.ExceptionAddress);
 			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.SP);  Trace.Ln();  Trace.String( "PC " );
 			Trace.Address(exceptionPointers.context.PC);  Trace.Ln();  
 			Trace.Address(exceptionPointers.context.PC);  Trace.Ln();  
 			
 			
@@ -714,7 +736,6 @@ BEGIN
 	res := Kernel32.TlsSetValue(tlsIndex, SYSTEM.VAL(LONGINT, lpParameter));
 	res := Kernel32.TlsSetValue(tlsIndex, SYSTEM.VAL(LONGINT, lpParameter));
 	t := lpParameter(Process);  obj := t.obj;
 	t := lpParameter(Process);  obj := t.obj;
 	ASSERT(res # 0);
 	ASSERT(res # 0);
-
 	SetPriority(t.priority);
 	SetPriority(t.priority);
 	bp := Machine.CurrentBP();
 	bp := Machine.CurrentBP();
 	sp := Machine.CurrentSP();
 	sp := Machine.CurrentSP();
@@ -1078,13 +1099,6 @@ BEGIN
 	TerminateProc();
 	TerminateProc();
 END Terminate;
 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 *)
 PROCEDURE Init;   (* can not use NEW *)
 VAR t: Process;  fn: Heaps.FinalizerNode;  proc: Kernel32.HANDLE;
 VAR t: Process;  fn: Heaps.FinalizerNode;  proc: Kernel32.HANDLE;
 	res: Kernel32.BOOL;
 	res: Kernel32.BOOL;
@@ -1260,12 +1274,14 @@ VAR GetProcedureName*: PROCEDURE (pc: ADDRESS; VAR n: ARRAY OF CHAR; VAR spc: AD
 PROCEDURE LeaveA2*;
 PROCEDURE LeaveA2*;
 VAR cur: Process; ebp,n: ADDRESS;
 VAR cur: Process; ebp,n: ADDRESS;
 BEGIN
 BEGIN
+	#IF WIN64 THEN	
 	CODE
 	CODE
 		PUSH RCX
 		PUSH RCX
 		PUSH RDX
 		PUSH RDX
 		PUSH R8
 		PUSH R8
 		PUSH R9
 		PUSH R9
 	END;
 	END;
+	#END
 	IF clock = NIL THEN 
 	IF clock = NIL THEN 
 		RETURN 
 		RETURN 
 	END;
 	END;
@@ -1281,12 +1297,14 @@ BEGIN
 		IF cur.gcContext.nextPos > 255 THEN cur.gcContext.nextPos := 255 END;
 		IF cur.gcContext.nextPos > 255 THEN cur.gcContext.nextPos := 255 END;
 		(* IF (cur.gcContext.nextPos > 4) THEN cur.gcContext.nextPos := 2 END;*)
 		(* IF (cur.gcContext.nextPos > 4) THEN cur.gcContext.nextPos := 2 END;*)
 	END;
 	END;
+	#IF WIN64 THEN
 	CODE
 	CODE
 		POP R9
 		POP R9
 		POP R8
 		POP R8
 		POP RDX
 		POP RDX
 		POP RCX
 		POP RCX
 	END;
 	END;
+	#END
 END LeaveA2;
 END LeaveA2;
 
 
 PROCEDURE ReenterA2*;
 PROCEDURE ReenterA2*;
@@ -1317,34 +1335,3 @@ BEGIN
 	
 	
 	Init;
 	Init;
 END Objects.
 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 ~