forked from KolibriOS/kolibrios
FreePascal RTL
git-svn-id: svn://kolibrios.org@616 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
34c712de5d
commit
f23fc38433
346
programs/develop/fp/exe2kos/exe2kos.pp
Normal file
346
programs/develop/fp/exe2kos/exe2kos.pp
Normal file
@ -0,0 +1,346 @@
|
||||
{$mode objfpc}
|
||||
{$apptype console}
|
||||
|
||||
program exe2kos;
|
||||
|
||||
uses
|
||||
SysUtils, Classes, ExeTypes, KosTypes;
|
||||
|
||||
const
|
||||
ARGS_SIZE = 512;
|
||||
PATH_SIZE = 512;
|
||||
|
||||
type
|
||||
EExeError = class(Exception);
|
||||
|
||||
TExeImage = class;
|
||||
TExeImageSection = class;
|
||||
|
||||
TExeImageSection = class
|
||||
private
|
||||
FExeImage: TExeImage;
|
||||
FHeader: IMAGE_SECTION_HEADER;
|
||||
FName: String;
|
||||
procedure Read(var Buffer);
|
||||
public
|
||||
constructor Create(AExeImage: TExeImage; APosition: DWord);
|
||||
property Name: String read FName;
|
||||
property VirtualSize: DWord read FHeader.PhysicalAddress;
|
||||
property SectionRVA: DWord read FHeader.VirtualAddress;
|
||||
property PhysicalSize: DWord read FHeader.SizeOfRawData;
|
||||
property PhysicalOffset: DWord read FHeader.PointerToRawData;
|
||||
property ObjectFlags: DWord read FHeader.Characteristics;
|
||||
end;
|
||||
|
||||
TExeImageSections = class
|
||||
private
|
||||
FCount: DWord;
|
||||
FItems: array of TExeImageSection;
|
||||
function GetItem(Index: DWord): TExeImageSection;
|
||||
public
|
||||
constructor Create(AExeImage: TExeImage; APosition, ACount: DWord);
|
||||
destructor Destroy; override;
|
||||
function ByName(AName: String): TExeImageSection;
|
||||
property Count: DWord read FCount;
|
||||
property Items[Index: DWord]: TExeImageSection read GetItem; default;
|
||||
end;
|
||||
|
||||
TExeImage = class
|
||||
private
|
||||
FFileName: String;
|
||||
FFileStream: TStream;
|
||||
FDosHeader: IMAGE_DOS_HEADER;
|
||||
FNTHeader: IMAGE_NT_HEADERS;
|
||||
FSections: TExeImageSections;
|
||||
procedure Read(var Buffer; Position, Size: Longint);
|
||||
function GetSizeOfCode(): DWord;
|
||||
function GetSizeOfInitData(): DWord;
|
||||
function GetSizeOfUnInitData(): DWord;
|
||||
function GetEntryPoint(): DWord;
|
||||
function GetImageBase(): DWord;
|
||||
function GetObjectAlign(): DWord;
|
||||
function GetFileAlign(): DWord;
|
||||
function GetImageSize(): DWord;
|
||||
function GetHeaderSize(): DWord;
|
||||
function GetStackReserveSize(): DWord;
|
||||
function GetStackCommitSize(): DWord;
|
||||
function GetHeapReserveSize(): DWord;
|
||||
function GetHeapCommitSize(): DWord;
|
||||
public
|
||||
constructor Create(AFileName: String);
|
||||
destructor Destroy; override;
|
||||
property FileName: String read FFileName;
|
||||
property Sections: TExeImageSections read FSections;
|
||||
property SizeOfCode: DWord read GetSizeOfCode;
|
||||
property SizeOfInitializedData: DWord read GetSizeOfInitData;
|
||||
property SizeOfUninitializedData: DWord read GetSizeOfUnInitData;
|
||||
property EntryPoint: DWord read FNTHeader.OptionalHeader.AddressOfEntryPoint{GetEntryPoint};
|
||||
property ImageBase: DWord read FNTHeader.OptionalHeader.ImageBase{GetImageBase};
|
||||
property ObjectAlign: DWord read GetObjectAlign;
|
||||
property FileAlign: DWord read GetFileAlign;
|
||||
property ImageSize: DWord read GetImageSize;
|
||||
property HeaderSize: DWord read GetHeaderSize;
|
||||
property StackReserveSize: DWord read GetStackReserveSize;
|
||||
property StackCommitSize: DWord read GetStackCommitSize;
|
||||
property HeapReserveSize: DWord read GetHeapReserveSize;
|
||||
property HeapCommitSize: DWord read GetHeapCommitSize;
|
||||
end;
|
||||
|
||||
|
||||
constructor TExeImage.Create(AFileName: String);
|
||||
begin
|
||||
FFileName := AFileName;
|
||||
FFileStream := TFileStream.Create(FFileName, fmOpenRead);
|
||||
|
||||
Read(FDosHeader, 0, SizeOf(FDosHeader));
|
||||
if not FDosHeader.e_magic = IMAGE_DOS_SIGNATURE then
|
||||
EExeError.Create('Unrecognized file format');
|
||||
|
||||
Read(FNTHeader, FDosHeader.e_lfanew, SizeOf(FNTHeader));
|
||||
if FNTHeader.Signature <> IMAGE_NT_SIGNATURE then
|
||||
EExeError.Create('Not a PE (WIN32 Executable) file');
|
||||
|
||||
FSections := TExeImageSections.Create(Self,
|
||||
FDosHeader.e_lfanew + SizeOf(FNTHeader), FNTHeader.FileHeader.NumberOfSections);
|
||||
end;
|
||||
|
||||
destructor TExeImage.Destroy;
|
||||
begin
|
||||
FSections.Free;
|
||||
FFileStream.Free;
|
||||
end;
|
||||
|
||||
procedure TExeImage.Read(var Buffer; Position, Size: Longint);
|
||||
begin
|
||||
FFileStream.Position := Position;
|
||||
if FFileStream.Read(Buffer, Size) <> Size then
|
||||
EExeError.Create('Damaged or unrecognized file');
|
||||
end;
|
||||
|
||||
function TExeImage.GetSizeOfCode(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfCode;
|
||||
end;
|
||||
|
||||
function TExeImage.GetSizeOfInitData(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfInitializedData;
|
||||
end;
|
||||
|
||||
function TExeImage.GetSizeOfUnInitData(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfUninitializedData;
|
||||
end;
|
||||
|
||||
function TExeImage.GetEntryPoint(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.AddressOfEntryPoint;
|
||||
end;
|
||||
|
||||
function TExeImage.GetImageBase(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.ImageBase;
|
||||
end;
|
||||
|
||||
function TExeImage.GetObjectAlign(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SectionAlignment;
|
||||
end;
|
||||
|
||||
function TExeImage.GetFileAlign(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.FileAlignment;
|
||||
end;
|
||||
|
||||
function TExeImage.GetImageSize(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfImage;
|
||||
end;
|
||||
|
||||
function TExeImage.GetHeaderSize(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfHeaders;
|
||||
end;
|
||||
|
||||
function TExeImage.GetStackReserveSize(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfStackReserve;
|
||||
end;
|
||||
|
||||
function TExeImage.GetStackCommitSize(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfStackCommit;
|
||||
end;
|
||||
|
||||
function TExeImage.GetHeapReserveSize(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfHeapReserve;
|
||||
end;
|
||||
|
||||
function TExeImage.GetHeapCommitSize(): DWord;
|
||||
begin
|
||||
Result := FNTHeader.OptionalHeader.SizeOfHeapCommit;
|
||||
end;
|
||||
|
||||
|
||||
constructor TExeImageSections.Create(AExeImage: TExeImage; APosition, ACount: DWord);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
FCount := ACount;
|
||||
SetLength(FItems, ACount);
|
||||
for i := 0 to ACount - 1 do
|
||||
begin
|
||||
FItems[i] := TExeImageSection.Create(AExeImage, APosition);
|
||||
Inc(APosition, SizeOf(IMAGE_SECTION_HEADER));
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TExeImageSections.Destroy;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to Length(FItems) - 1 do FItems[i].Free;
|
||||
SetLength(FItems, 0);
|
||||
end;
|
||||
|
||||
function TExeImageSections.GetItem(Index: DWord): TExeImageSection;
|
||||
begin
|
||||
Result := FItems[Index];
|
||||
end;
|
||||
|
||||
function TExeImageSections.ByName(AName: String): TExeImageSection;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to Length(FItems) - 1 do
|
||||
if FItems[i].Name = AName then
|
||||
begin
|
||||
Result := FItems[i];
|
||||
Exit;
|
||||
end;
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
constructor TExeImageSection.Create(AExeImage: TExeImage; APosition: DWord);
|
||||
begin
|
||||
FExeImage := AExeImage;
|
||||
FExeImage.Read(FHeader, APosition, SizeOf(FHeader));
|
||||
FName := FHeader.Name;
|
||||
end;
|
||||
|
||||
procedure TExeImageSection.Read(var Buffer);
|
||||
begin
|
||||
FExeImage.Read(Buffer, PhysicalOffset, PhysicalSize);
|
||||
end;
|
||||
|
||||
|
||||
procedure WriteHead(s: String);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
WriteLn;
|
||||
WriteLn(s);
|
||||
for i:=1 to Length(s) do Write('-');
|
||||
WriteLn;
|
||||
end;
|
||||
|
||||
procedure Convert(InputFile, OutputFile: String);
|
||||
var
|
||||
ExeImage: TExeImage;
|
||||
KosHeader: TKosHeader;
|
||||
FileStream: TStream;
|
||||
ImageBase, ImageSize, Size: DWord;
|
||||
Buffer: Pointer;
|
||||
i: Integer;
|
||||
begin
|
||||
ExeImage := TExeImage.Create(InputFile);
|
||||
WriteHead('NT Header');
|
||||
WriteLn(Format('Size of Code: %d', [ExeImage.SizeOfCode]));
|
||||
WriteLn(Format('Size of Init Data: %d', [ExeImage.SizeOfInitializedData]));
|
||||
WriteLn(Format('Size of UnInit Data: %d', [ExeImage.SizeOfUninitializedData]));
|
||||
WriteLn(Format('Entry Point: 0x%x', [ExeImage.EntryPoint]));
|
||||
WriteLn(Format('Image Base: 0x%x', [ExeImage.ImageBase]));
|
||||
WriteLn(Format('Object Align: %d; File Align: %d', [ExeImage.ObjectAlign, ExeImage.FileAlign]));
|
||||
WriteLn(Format('Image Size: %d; Header Size: %d', [ExeImage.ImageSize, ExeImage.HeaderSize]));
|
||||
WriteLn(Format('Stack Reserve Size: %d; Stack Commit Size: %d', [ExeImage.StackReserveSize, ExeImage.StackCommitSize]));
|
||||
WriteLn(Format('Heap Reserve Size: %d; Heap Comit Size: %d', [ExeImage.HeapReserveSize, ExeImage.HeapCommitSize]));
|
||||
|
||||
ImageBase := ExeImage.ImageBase;
|
||||
ImageSize := 0;
|
||||
|
||||
{ çàïèñü ñåêöèé }
|
||||
FileStream := TFileStream.Create(OutputFile, fmCreate);
|
||||
for i:=0 to ExeImage.Sections.Count-1 do
|
||||
with ExeImage.Sections[i] do
|
||||
begin
|
||||
WriteHead(Format('Section %s (0x%x)', [Name, ObjectFlags]));
|
||||
WriteLn(Format('Section RVA/Size: 0x%x / %d', [SectionRVA, VirtualSize]));
|
||||
WriteLn(Format('Physical Offset/Size: 0x%x / %d', [PhysicalOffset, PhysicalSize]));
|
||||
|
||||
Size := ImageBase + SectionRVA;
|
||||
FileStream.Position := Size;
|
||||
Inc(Size, VirtualSize);
|
||||
if Size > ImageSize then ImageSize := Size;
|
||||
|
||||
if PhysicalSize > 0 then
|
||||
begin
|
||||
GetMem(Buffer, PhysicalSize);
|
||||
Read(Buffer^);
|
||||
FileStream.Write(Buffer^, PhysicalSize);
|
||||
FreeMem(Buffer);
|
||||
end;
|
||||
{if VirtualSize - PhysicalSize > 0 then
|
||||
begin
|
||||
GetMem(Buffer, VirtualSize - PhysicalSize);
|
||||
FillByte(Buffer^, VirtualSize - PhysicalSize, 0);
|
||||
FileStream.Write(Buffer^, VirtualSize - PhysicalSize);
|
||||
FreeMem(Buffer);
|
||||
end;}
|
||||
end;
|
||||
|
||||
FillByte(KosHeader, SizeOf(KosHeader), 0);
|
||||
with KosHeader do
|
||||
begin
|
||||
sign := KOS_SIGN;
|
||||
version := 1;
|
||||
start := ImageBase + ExeImage.EntryPoint;
|
||||
size := FileStream.Size;
|
||||
args := ImageSize;
|
||||
path := args + ARGS_SIZE;
|
||||
stack := path + PATH_SIZE + ExeImage.StackReserveSize;
|
||||
memory := stack;
|
||||
end;
|
||||
FileStream.Position := 0;
|
||||
FileStream.Write(KosHeader, SizeOf(KosHeader));
|
||||
FileStream.Free();
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
InputFile, OutputFile: String;
|
||||
begin
|
||||
if ParamCount < 1 then
|
||||
begin
|
||||
WriteLn(Format('%s <exe input file> [kos output file]', [ExtractFileName(ParamStr(0))]));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
InputFile := ParamStr(1);
|
||||
if ParamCount <2 then
|
||||
OutputFile := ChangeFileExt(InputFile, '') else
|
||||
OutputFile := ParamStr(2);
|
||||
|
||||
if InputFile = OutputFile then
|
||||
WriteLn(Format('Cannot convert the file "%s" onto itself.', [InputFile])) else
|
||||
|
||||
if not FileExists(InputFile) then
|
||||
WriteLn(Format('Input the file "%s", not found.', [InputFile])) else
|
||||
|
||||
begin
|
||||
WriteLn(Format('Converting "%s" to "%s"...', [InputFile, OutputFile]));
|
||||
Convert(InputFile, OutputFile);
|
||||
end;
|
||||
end.
|
827
programs/develop/fp/exe2kos/exeimage.pp
Normal file
827
programs/develop/fp/exe2kos/exeimage.pp
Normal file
@ -0,0 +1,827 @@
|
||||
{$mode delphi}
|
||||
|
||||
unit ExeImage;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
TypInfo, Classes, SysUtils, Windows, RXTypes;
|
||||
|
||||
const
|
||||
MF_END = $80;
|
||||
|
||||
type
|
||||
|
||||
{ Exceptions }
|
||||
|
||||
EExeError = class(Exception);
|
||||
ENotImplemented = class(Exception)
|
||||
public
|
||||
constructor Create();
|
||||
end;
|
||||
|
||||
{ Forward Declarations }
|
||||
|
||||
TResourceItem = class;
|
||||
TResourceClass = class of TResourceItem;
|
||||
TResourceList = class;
|
||||
|
||||
{ TExeImage }
|
||||
|
||||
TExeImage = class(TComponent)
|
||||
private
|
||||
FFileName: string;
|
||||
FFileHandle: THandle;
|
||||
FFileMapping: THandle;
|
||||
FFileBase: Pointer;
|
||||
FDosHeader: PIMAGE_DOS_HEADER;
|
||||
FNTHeader: PIMAGE_NT_HEADERS;
|
||||
FResourceList: TResourceList;
|
||||
FIconResources: TResourceItem;
|
||||
FCursorResources: TResourceItem;
|
||||
FResourceBase: Longint;
|
||||
FResourceRVA: Longint;
|
||||
function GetResourceList: TResourceList;
|
||||
function GetSectionHdr(const SectionName: string;
|
||||
var Header: PIMAGE_SECTION_HEADER): Boolean;
|
||||
public
|
||||
constructor CreateImage(AOwner: TComponent; const AFileName: string);
|
||||
destructor Destroy; override;
|
||||
property FileName: string read FFileName;
|
||||
property Resources: TResourceList read GetResourceList;
|
||||
end;
|
||||
|
||||
{ TResourceItem }
|
||||
|
||||
TResourceItem = class(TComponent)
|
||||
private
|
||||
FList: TResourceList;
|
||||
FDirEntry: PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
function DataEntry: PIMAGE_RESOURCE_DATA_ENTRY;
|
||||
function FExeImage: TExeImage;
|
||||
function FirstChildDirEntry: PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
function GetResourceItem(Index: Integer): TResourceItem;
|
||||
function GetResourceType: TResourceType;
|
||||
protected
|
||||
function GetName: string; virtual;
|
||||
function GetResourceList: TResourceList; virtual;
|
||||
public
|
||||
constructor CreateItem(AOwner: TComponent; ADirEntry: Pointer);
|
||||
function IsList: Boolean; virtual;
|
||||
function Offset: Integer;
|
||||
function Size: Integer;
|
||||
function RawData: Pointer;
|
||||
function ResTypeStr: string;
|
||||
procedure SaveToFile(const FileName: string);
|
||||
procedure SaveToStream(Stream: TStream); virtual;
|
||||
property Items[Index: Integer]: TResourceItem read GetResourceItem; default;
|
||||
property List: TResourceList read GetResourceList;
|
||||
property Name: string read GetName;
|
||||
property ResType: TResourceType read GetResourceType;
|
||||
end;
|
||||
|
||||
{ TIconResource }
|
||||
|
||||
TIconResource = class(TResourceItem)
|
||||
protected
|
||||
function GetResourceList: TResourceList; override;
|
||||
public
|
||||
function IsList: Boolean; override;
|
||||
end;
|
||||
|
||||
{ TIconResEntry }
|
||||
|
||||
TIconResEntry = class(TResourceItem)
|
||||
protected
|
||||
FResInfo: PIconResInfo;
|
||||
function GetName: string; override;
|
||||
procedure AssignTo(Dest: TPersistent); override;
|
||||
public
|
||||
procedure SaveToStream(Stream: TStream); override;
|
||||
end;
|
||||
|
||||
{ TCursorResource }
|
||||
|
||||
TCursorResource = class(TIconResource)
|
||||
protected
|
||||
function GetResourceList: TResourceList; override;
|
||||
end;
|
||||
|
||||
{ TCursorResEntry }
|
||||
|
||||
TCursorResEntry = class(TIconResEntry)
|
||||
protected
|
||||
FResInfo: PCursorResInfo;
|
||||
function GetName: string; override;
|
||||
end;
|
||||
|
||||
{ TBitmapResource }
|
||||
|
||||
TBitmapResource = class(TResourceItem)
|
||||
protected
|
||||
procedure AssignTo(Dest: TPersistent); override;
|
||||
public
|
||||
procedure SaveToStream(Stream: TStream); override;
|
||||
end;
|
||||
|
||||
{ TStringResource }
|
||||
|
||||
TStringResource = class(TResourceItem)
|
||||
protected
|
||||
procedure AssignTo(Dest: TPersistent); override;
|
||||
end;
|
||||
|
||||
{ TMenuResource }
|
||||
|
||||
TMenuResource = class(TResourceItem)
|
||||
private
|
||||
FNestStr: string;
|
||||
FNestLevel: Integer;
|
||||
procedure SetNestLevel(Value: Integer);
|
||||
protected
|
||||
procedure AssignTo(Dest: TPersistent); override;
|
||||
property NestLevel: Integer read FNestLevel write SetNestLevel;
|
||||
property NestStr: string read FNestStr;
|
||||
end;
|
||||
|
||||
{ TResourceList }
|
||||
|
||||
TResourceList = class(TComponent)
|
||||
protected
|
||||
FList: TList;
|
||||
FResDir: PIMAGE_RESOURCE_DIRECTORY;
|
||||
FExeImage: TExeImage;
|
||||
FResType: Integer;
|
||||
function List: TList; virtual;
|
||||
function GetResourceItem(Index: Integer): TResourceItem;
|
||||
public
|
||||
constructor CreateList(AOwner: TComponent; ResDirOfs: Longint;
|
||||
AExeImage: TExeImage);
|
||||
destructor Destroy; override;
|
||||
function Count: Integer;
|
||||
property Items[Index: Integer]: TResourceItem read GetResourceItem; default;
|
||||
end;
|
||||
|
||||
{ TIconResourceList }
|
||||
|
||||
TIconResourceList = class(TResourceList)
|
||||
protected
|
||||
function List: TList; override;
|
||||
end;
|
||||
|
||||
{ TCursorResourceList }
|
||||
|
||||
TCursorResourceList = class(TResourceList)
|
||||
protected
|
||||
function List: TList; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor ENotImplemented.Create();
|
||||
begin
|
||||
inherited Create('Not Implemented');
|
||||
end;
|
||||
|
||||
|
||||
{ This function maps a resource type to the associated resource class }
|
||||
|
||||
function GetResourceClass(ResType: Integer): TResourceClass;
|
||||
const
|
||||
TResourceClasses: array[TResourceType] of TResourceClass = (
|
||||
TResourceItem, { rtUnknown0 }
|
||||
TCursorResEntry, { rtCursorEntry }
|
||||
TBitmapResource, { rtBitmap }
|
||||
TIconResEntry, { rtIconEntry }
|
||||
TMenuResource, { rtMenu }
|
||||
TResourceItem, { rtDialog }
|
||||
TStringResource, { rtString }
|
||||
TResourceItem, { rtFontDir }
|
||||
TResourceItem, { rtFont }
|
||||
TResourceItem, { rtAccelerators }
|
||||
TResourceItem, { rtRCData }
|
||||
TResourceItem, { rtMessageTable }
|
||||
TCursorResource, { rtGroupCursor }
|
||||
TResourceItem, { rtUnknown13 }
|
||||
TIconResource, { rtIcon }
|
||||
TResourceItem, { rtUnknown15 }
|
||||
TResourceItem); { rtVersion }
|
||||
begin
|
||||
if (ResType >= Integer(Low(TResourceType))) and
|
||||
(ResType <= Integer(High(TResourceType))) then
|
||||
Result := TResourceClasses[TResourceType(ResType)] else
|
||||
Result := TResourceItem;
|
||||
end;
|
||||
|
||||
{ Utility Functions }
|
||||
|
||||
function Min(A, B: Integer): Integer;
|
||||
begin
|
||||
if A < B then Result := A
|
||||
else Result := B;
|
||||
end;
|
||||
|
||||
{ This function checks if an offset is a string name, or a directory }
|
||||
{Assumes: IMAGE_RESOURCE_NAME_IS_STRING = IMAGE_RESOURCE_DATA_IS_DIRECTORY}
|
||||
|
||||
function HighBitSet(L: Longint): Boolean;
|
||||
begin
|
||||
Result := (L and IMAGE_RESOURCE_DATA_IS_DIRECTORY) <> 0;
|
||||
end;
|
||||
|
||||
function StripHighBit(L: Longint): Longint;
|
||||
begin
|
||||
Result := L and IMAGE_OFFSET_STRIP_HIGH;
|
||||
end;
|
||||
|
||||
function StripHighPtr(L: Longint): Pointer;
|
||||
begin
|
||||
Result := Pointer(L and IMAGE_OFFSET_STRIP_HIGH);
|
||||
end;
|
||||
|
||||
{ This function converts a pointer to a wide char string into a pascal string }
|
||||
|
||||
function WideCharToStr(WStr: PWChar; Len: Integer): string;
|
||||
begin
|
||||
if Len = 0 then Len := -1;
|
||||
Len := WideCharToMultiByte(CP_ACP, 0, WStr, Len, nil, 0, nil, nil);
|
||||
SetLength(Result, Len);
|
||||
WideCharToMultiByte(CP_ACP, 0, WStr, Len, PChar(Result), Len, nil, nil);
|
||||
end;
|
||||
|
||||
{ Exceptions }
|
||||
|
||||
procedure ExeError(const ErrMsg: string);
|
||||
begin
|
||||
raise EExeError.Create(ErrMsg);
|
||||
end;
|
||||
|
||||
{ TExeImage }
|
||||
|
||||
constructor TExeImage.CreateImage(AOwner: TComponent; const AFileName: string);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FFileName := AFileName;
|
||||
FFileHandle := CreateFile(PChar(FFileName), GENERIC_READ, FILE_SHARE_READ,
|
||||
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if FFileHandle = INVALID_HANDLE_VALUE then ExeError('Couldn''t open: '+FFileName);
|
||||
FFileMapping := CreateFileMapping(FFileHandle, nil, PAGE_READONLY, 0, 0, nil);
|
||||
if FFileMapping = 0 then ExeError('CreateFileMapping failed');
|
||||
FFileBase := MapViewOfFile(FFileMapping, FILE_MAP_READ, 0, 0, 0);
|
||||
if FFileBase = nil then ExeError('MapViewOfFile failed');
|
||||
FDosHeader := PIMAGE_DOS_HEADER(FFileBase);
|
||||
if not FDosHeader.e_magic = IMAGE_DOS_SIGNATURE then
|
||||
ExeError('unrecognized file format');
|
||||
FNTHeader := PIMAGE_NT_HEADERS(Longint(FDosHeader) + FDosHeader.e_lfanew);
|
||||
if IsBadReadPtr(FNTHeader, sizeof(IMAGE_NT_HEADERS)) or
|
||||
(FNTHeader.Signature <> IMAGE_NT_SIGNATURE) then
|
||||
ExeError('Not a PE (WIN32 Executable) file');
|
||||
end;
|
||||
|
||||
destructor TExeImage.Destroy;
|
||||
begin
|
||||
if FFileHandle <> INVALID_HANDLE_VALUE then
|
||||
begin
|
||||
UnmapViewOfFile(FFileBase);
|
||||
CloseHandle(FFileMapping);
|
||||
CloseHandle(FFileHandle);
|
||||
end;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TExeImage.GetSectionHdr(const SectionName: string;
|
||||
var Header: PIMAGE_SECTION_HEADER): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
Header := PIMAGE_SECTION_HEADER(FNTHeader);
|
||||
Inc(PIMAGE_NT_HEADERS(Header));
|
||||
Result := True;
|
||||
for I := 0 to FNTHeader.FileHeader.NumberOfSections - 1 do
|
||||
begin
|
||||
if Strlicomp(Header.Name, PChar(SectionName), IMAGE_SIZEOF_SHORT_NAME) = 0 then Exit;
|
||||
Inc(Header);
|
||||
end;
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function TExeImage.GetResourceList: TResourceList;
|
||||
var
|
||||
ResSectHdr: PIMAGE_SECTION_HEADER;
|
||||
begin
|
||||
if not Assigned(FResourceList) then
|
||||
begin
|
||||
if GetSectionHdr('.rsrc', ResSectHdr) then
|
||||
begin
|
||||
FResourceBase := ResSectHdr.PointerToRawData + LongWord(FDosHeader);
|
||||
FResourceRVA := ResSectHdr.VirtualAddress;
|
||||
FResourceList := TResourceList.CreateList(Self, FResourceBase, Self);
|
||||
end
|
||||
else
|
||||
ExeError('No resources in this file.');
|
||||
end;
|
||||
Result := FResourceList;
|
||||
end;
|
||||
|
||||
{ TResourceItem }
|
||||
|
||||
constructor TResourceItem.CreateItem(AOwner: TComponent; ADirEntry: Pointer);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FDirEntry := ADirEntry;
|
||||
end;
|
||||
|
||||
function TResourceItem.DataEntry: PIMAGE_RESOURCE_DATA_ENTRY;
|
||||
begin
|
||||
Result := PIMAGE_RESOURCE_DATA_ENTRY(FirstChildDirEntry.OffsetToData
|
||||
+ Cardinal(FExeImage.FResourceBase));
|
||||
end;
|
||||
|
||||
function TResourceItem.FirstChildDirEntry: PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
begin
|
||||
Result := PIMAGE_RESOURCE_DIRECTORY_ENTRY(StripHighBit(FDirEntry.OffsetToData) +
|
||||
FExeImage.FResourceBase + SizeOf(IMAGE_RESOURCE_DIRECTORY));
|
||||
end;
|
||||
|
||||
function TResourceItem.FExeImage: TExeImage;
|
||||
begin
|
||||
Result := (Owner as TResourceList).FExeImage;
|
||||
end;
|
||||
|
||||
function TResourceItem.GetResourceItem(Index: Integer): TResourceItem;
|
||||
begin
|
||||
Result := List[Index];
|
||||
end;
|
||||
|
||||
function TResourceItem.GetResourceType: TResourceType;
|
||||
begin
|
||||
Result := TResourceType((Owner as TResourceList).FResType);
|
||||
end;
|
||||
|
||||
function TResourceItem.IsList: Boolean;
|
||||
begin
|
||||
Result := HighBitSet(FirstChildDirEntry.OffsetToData);
|
||||
end;
|
||||
|
||||
function TResourceItem.GetResourceList: TResourceList;
|
||||
begin
|
||||
if not IsList then ExeError('ResourceItem is not a list');
|
||||
if not Assigned(FList) then
|
||||
FList := TResourceList.CreateList(Self, StripHighBit(FDirEntry.OffsetToData) +
|
||||
FExeImage.FResourceBase, FExeImage);
|
||||
Result := FList;
|
||||
end;
|
||||
|
||||
function TResourceItem.GetName: string;
|
||||
var
|
||||
PDirStr: PIMAGE_RESOURCE_DIR_STRING_U;
|
||||
begin
|
||||
{ Check for Level1 entries, these are resource types. }
|
||||
if (Owner.Owner = FExeImage) and not HighBitSet(FDirEntry.Name) and
|
||||
(FDirEntry.Name <= 16) then
|
||||
begin
|
||||
Result := Copy(GetEnumName(TypeInfo(TResourceType), FDirEntry.Name), 3, 20);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if HighBitSet(FDirEntry.Name) then
|
||||
begin
|
||||
PDirStr := PIMAGE_RESOURCE_DIR_STRING_U(StripHighBit(FDirEntry.Name) +
|
||||
FExeImage.FResourceBase);
|
||||
Result := WideCharToStr(@PDirStr.NameString, PDirStr.Length);
|
||||
Exit;
|
||||
end;
|
||||
Result := Format('%d', [FDirEntry.Name]);
|
||||
end;
|
||||
|
||||
function TResourceItem.Offset: Integer;
|
||||
begin
|
||||
if IsList then
|
||||
Result := StripHighBit(FDirEntry.OffsetToData)
|
||||
else
|
||||
Result := DataEntry.OffsetToData;
|
||||
end;
|
||||
|
||||
function TResourceItem.RawData: Pointer;
|
||||
begin
|
||||
with FExeImage do
|
||||
Result := pointer(FResourceBase - FResourceRVA + LongInt(DataEntry.OffsetToData));
|
||||
end;
|
||||
|
||||
function TResourceItem.ResTypeStr: string;
|
||||
begin
|
||||
Result := Copy(GetEnumName(TypeInfo(TResourceType), Ord(ResType)), 3, 20);
|
||||
end;
|
||||
|
||||
procedure TResourceItem.SaveToFile(const FileName: string);
|
||||
var
|
||||
FS: TFileStream;
|
||||
begin
|
||||
FS := TFileStream.Create(FileName, fmCreate);
|
||||
try
|
||||
Self.SaveToStream(FS);
|
||||
finally
|
||||
FS.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TResourceItem.SaveToStream(Stream: TStream);
|
||||
begin
|
||||
Stream.Write(RawData^, Size);
|
||||
end;
|
||||
|
||||
function TResourceItem.Size: Integer;
|
||||
begin
|
||||
if IsList then
|
||||
Result := 0
|
||||
else
|
||||
Result := DataEntry.Size;
|
||||
end;
|
||||
|
||||
{ TBitmapResource }
|
||||
|
||||
procedure TBitmapResource.AssignTo(Dest: TPersistent);
|
||||
{var
|
||||
MemStr: TMemoryStream;
|
||||
BitMap: TBitMap;}
|
||||
begin
|
||||
raise ENotImplemented.Create();
|
||||
|
||||
{if (Dest is TPicture) then
|
||||
begin
|
||||
BitMap := TPicture(Dest).Bitmap;
|
||||
MemStr := TMemoryStream.Create;
|
||||
try
|
||||
SaveToStream(MemStr);
|
||||
MemStr.Seek(0,0);
|
||||
BitMap.LoadFromStream(MemStr);
|
||||
finally
|
||||
MemStr.Free;
|
||||
end
|
||||
end
|
||||
else
|
||||
inherited AssignTo(Dest);}
|
||||
end;
|
||||
|
||||
procedure TBitmapResource.SaveToStream(Stream: TStream);
|
||||
|
||||
{function GetDInColors(BitCount: Word): Integer;
|
||||
begin
|
||||
case BitCount of
|
||||
1, 4, 8: Result := 1 shl BitCount;
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
BH: TBitmapFileHeader;
|
||||
BI: PBitmapInfoHeader;
|
||||
BC: PBitmapCoreHeader;
|
||||
ClrUsed: Integer;}
|
||||
begin
|
||||
raise ENotImplemented.Create();
|
||||
|
||||
{FillChar(BH, sizeof(BH), #0);
|
||||
BH.bfType := $4D42;
|
||||
BH.bfSize := Self.Size + sizeof(BH);
|
||||
BI := PBitmapInfoHeader(RawData);
|
||||
if BI.biSize = sizeof(TBitmapInfoHeader) then
|
||||
begin
|
||||
ClrUsed := BI.biClrUsed;
|
||||
if ClrUsed = 0 then
|
||||
ClrUsed := GetDInColors(BI.biBitCount);
|
||||
BH.bfOffBits := ClrUsed * SizeOf(TRgbQuad) +
|
||||
sizeof(TBitmapInfoHeader) + sizeof(BH);
|
||||
end
|
||||
else
|
||||
begin
|
||||
BC := PBitmapCoreHeader(RawData);
|
||||
ClrUsed := GetDInColors(BC.bcBitCount);
|
||||
BH.bfOffBits := ClrUsed * SizeOf(TRGBTriple) +
|
||||
sizeof(TBitmapCoreHeader) + sizeof(BH);
|
||||
end;
|
||||
Stream.Write(BH, SizeOf(BH));
|
||||
Stream.Write(RawData^, Self.Size);}
|
||||
end;
|
||||
|
||||
|
||||
{ TIconResource }
|
||||
|
||||
function TIconResource.GetResourceList: TResourceList;
|
||||
begin
|
||||
if not Assigned(FList) then
|
||||
FList := TIconResourceList.CreateList(Owner, LongInt(RawData), FExeImage);
|
||||
Result := FList;
|
||||
end;
|
||||
|
||||
function TIconResource.IsList: Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
{ TIconResEntry }
|
||||
|
||||
procedure TIconResEntry.AssignTo(Dest: TPersistent);
|
||||
{var
|
||||
hIco: HIcon;}
|
||||
begin
|
||||
raise ENotImplemented.Create();
|
||||
|
||||
{if Dest is TPicture then
|
||||
begin
|
||||
hIco := CreateIconFromResource(RawData, Size, (ResType = rtIconEntry), $30000);
|
||||
TPicture(Dest).Icon.Handle := hIco;
|
||||
end
|
||||
else
|
||||
inherited AssignTo(Dest);}
|
||||
end;
|
||||
|
||||
function TIconResEntry.GetName: string;
|
||||
begin
|
||||
if Assigned(FResInfo) then
|
||||
with FResInfo^ do
|
||||
Result := Format('%d X %d %d Colors', [bWidth, bHeight, bColorCount])
|
||||
else
|
||||
Result := inherited GetName;
|
||||
end;
|
||||
|
||||
procedure TIconResEntry.SaveToStream(Stream: TStream);
|
||||
begin
|
||||
raise ENotImplemented.Create();
|
||||
|
||||
{with TIcon.Create do
|
||||
try
|
||||
Handle := CreateIconFromResource(RawData, Self.Size, (ResType <> rtIcon), $30000);
|
||||
SaveToStream(Stream);
|
||||
finally
|
||||
Free;
|
||||
end;}
|
||||
end;
|
||||
|
||||
{ TCursorResource }
|
||||
|
||||
function TCursorResource.GetResourceList: TResourceList;
|
||||
begin
|
||||
if not Assigned(FList) then
|
||||
FList := TCursorResourceList.CreateList(Owner, LongInt(RawData), FExeImage);
|
||||
Result := FList;
|
||||
end;
|
||||
|
||||
{ TCursorResEntry }
|
||||
|
||||
function TCursorResEntry.GetName: string;
|
||||
begin
|
||||
if Assigned(FResInfo) then
|
||||
with FResInfo^ do
|
||||
Result := Format('%d X %d %d Bit(s)', [wWidth, wWidth, wBitCount])
|
||||
else
|
||||
Result := inherited GetName;
|
||||
end;
|
||||
|
||||
{ TStringResource }
|
||||
|
||||
procedure TStringResource.AssignTo(Dest: TPersistent);
|
||||
var
|
||||
P: PWChar;
|
||||
ID: Integer;
|
||||
Cnt: Cardinal;
|
||||
Len: Word;
|
||||
begin
|
||||
if (Dest is TStrings) then
|
||||
with TStrings(Dest) do
|
||||
begin
|
||||
BeginUpdate;
|
||||
try
|
||||
Clear;
|
||||
P := RawData;
|
||||
Cnt := 0;
|
||||
while Cnt < StringsPerBlock do
|
||||
begin
|
||||
Len := Word(P^);
|
||||
if Len > 0 then
|
||||
begin
|
||||
Inc(P);
|
||||
ID := ((FDirEntry.Name - 1) shl 4) + Cnt;
|
||||
Add(Format('%d, "%s"', [ID, WideCharToStr(P, Len)]));
|
||||
Inc(P, Len);
|
||||
end;
|
||||
Inc(Cnt);
|
||||
end;
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
end
|
||||
else
|
||||
inherited AssignTo(Dest);
|
||||
end;
|
||||
|
||||
{ TMenuResource }
|
||||
|
||||
procedure TMenuResource.SetNestLevel(Value: Integer);
|
||||
begin
|
||||
FNestLevel := Value;
|
||||
SetLength(FNestStr, Value * 2);
|
||||
FillChar(FNestStr[1], Value * 2, ' ');
|
||||
end;
|
||||
|
||||
procedure TMenuResource.AssignTo(Dest: TPersistent);
|
||||
var
|
||||
IsPopup: Boolean;
|
||||
Len: Word;
|
||||
MenuData: PWord;
|
||||
MenuEnd: PChar;
|
||||
MenuText: PWChar;
|
||||
MenuID: Word;
|
||||
MenuFlags: Word;
|
||||
S: string;
|
||||
begin
|
||||
if (Dest is TStrings) then
|
||||
with TStrings(Dest) do
|
||||
begin
|
||||
BeginUpdate;
|
||||
try
|
||||
Clear;
|
||||
MenuData := RawData;
|
||||
MenuEnd := PChar(RawData) + Size;
|
||||
Inc(MenuData, 2);
|
||||
NestLevel := 0;
|
||||
while PChar(MenuData) < MenuEnd do
|
||||
begin
|
||||
MenuFlags := MenuData^;
|
||||
Inc(MenuData);
|
||||
IsPopup := (MenuFlags and MF_POPUP) = MF_POPUP;
|
||||
MenuID := 0;
|
||||
if not IsPopup then
|
||||
begin
|
||||
MenuID := MenuData^;
|
||||
Inc(MenuData);
|
||||
end;
|
||||
MenuText := PWChar(MenuData);
|
||||
Len := lstrlenw(MenuText);
|
||||
if Len = 0 then
|
||||
S := 'MENUITEM SEPARATOR'
|
||||
else
|
||||
begin
|
||||
S := WideCharToStr(MenuText, Len);
|
||||
if IsPopup then
|
||||
S := Format('POPUP "%s"', [S]) else
|
||||
S := Format('MENUITEM "%s", %d', [S, MenuID]);
|
||||
end;
|
||||
Inc(MenuData, Len + 1);
|
||||
Add(NestStr + S);
|
||||
if (MenuFlags and MF_END) = MF_END then
|
||||
begin
|
||||
NestLevel := NestLevel - 1;
|
||||
Add(NestStr + 'ENDPOPUP');
|
||||
end;
|
||||
if IsPopup then
|
||||
NestLevel := NestLevel + 1;
|
||||
end;
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
end
|
||||
else
|
||||
inherited AssignTo(Dest);
|
||||
end;
|
||||
|
||||
{ TResourceList }
|
||||
|
||||
constructor TResourceList.CreateList(AOwner: TComponent; ResDirOfs: Longint;
|
||||
AExeImage: TExeImage);
|
||||
var
|
||||
DirEntry: PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FExeImage := AExeImage;
|
||||
FResDir := Pointer(ResDirOfs);
|
||||
if AOwner <> AExeImage then
|
||||
if AOwner.Owner.Owner = AExeImage then
|
||||
begin
|
||||
DirEntry := PIMAGE_RESOURCE_DIRECTORY_ENTRY(FResDir);
|
||||
inc(PIMAGE_RESOURCE_DIRECTORY(DirEntry));
|
||||
FResType := TResourceItem(Owner).FDirEntry.Name;
|
||||
end
|
||||
else
|
||||
FResType := (AOwner.Owner.Owner as TResourceList).FResType;
|
||||
end;
|
||||
|
||||
destructor TResourceList.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
FList.Free;
|
||||
end;
|
||||
|
||||
function TResourceList.List: TList;
|
||||
var
|
||||
I: Integer;
|
||||
DirEntry: PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
DirCnt: Integer;
|
||||
ResItem: TResourceItem;
|
||||
begin
|
||||
if not Assigned(FList) then
|
||||
begin
|
||||
FList := TList.Create;
|
||||
DirEntry := PIMAGE_RESOURCE_DIRECTORY_ENTRY(FResDir);
|
||||
inc(PIMAGE_RESOURCE_DIRECTORY(DirEntry));
|
||||
DirCnt := FResDir.NumberOfNamedEntries + FResDir.NumberOfIdEntries - 1;
|
||||
for I := 0 to DirCnt do
|
||||
begin
|
||||
{ Handle Cursors and Icons specially }
|
||||
ResItem := GetResourceClass(FResType).CreateItem(Self, DirEntry);
|
||||
if Owner = FExeImage then
|
||||
if (TResourceType(DirEntry.Name) in [rtCursorEntry, rtIconEntry]) then
|
||||
begin
|
||||
if TResourceType(DirEntry.Name) = rtCursorEntry then
|
||||
FExeImage.FCursorResources := ResItem else
|
||||
FExeImage.FIconResources := ResItem;
|
||||
Inc(DirEntry);
|
||||
Continue;
|
||||
end;
|
||||
FList.Add(ResItem);
|
||||
Inc(DirEntry);
|
||||
end;
|
||||
end;
|
||||
Result := FList;
|
||||
end;
|
||||
|
||||
function TResourceList.Count: Integer;
|
||||
begin
|
||||
Result := List.Count;
|
||||
end;
|
||||
|
||||
function TResourceList.GetResourceItem(Index: Integer): TResourceItem;
|
||||
begin
|
||||
Result := List[Index];
|
||||
end;
|
||||
|
||||
{ TIconResourceList }
|
||||
|
||||
function TIconResourceList.List: TList;
|
||||
var
|
||||
I, J, Cnt: Integer;
|
||||
ResData: PIconResInfo;
|
||||
ResList: TResourceList;
|
||||
ResOrd: Cardinal;
|
||||
IconResource: TIconResEntry;
|
||||
begin
|
||||
if not Assigned(FList) then
|
||||
begin
|
||||
FList := TList.Create;
|
||||
Cnt := PIconHeader(FResDir).wCount;
|
||||
PChar(ResData) := PChar(FResDir) + SizeOf(TIconHeader);
|
||||
ResList := FExeImage.FIconResources.List;
|
||||
for I := 0 to Cnt - 1 do
|
||||
begin
|
||||
ResOrd := ResData.wNameOrdinal;
|
||||
for J := 0 to ResList.Count - 1 do
|
||||
begin
|
||||
if ResOrd = ResList[J].FDirEntry.Name then
|
||||
begin
|
||||
IconResource := ResList[J] as TIconResEntry;
|
||||
IconResource.FResInfo := ResData;
|
||||
FList.Add(IconResource);
|
||||
end;
|
||||
end;
|
||||
Inc(ResData);
|
||||
end;
|
||||
end;
|
||||
Result := FList;
|
||||
end;
|
||||
|
||||
{ TCursorResourceList }
|
||||
|
||||
function TCursorResourceList.List: TList;
|
||||
var
|
||||
I, J, Cnt: Integer;
|
||||
ResData: PCursorResInfo;
|
||||
ResList: TResourceList;
|
||||
ResOrd: Cardinal;
|
||||
CursorResource: TCursorResEntry;
|
||||
begin
|
||||
if not Assigned(FList) then
|
||||
begin
|
||||
FList := TList.Create;
|
||||
Cnt := PIconHeader(FResDir).wCount;
|
||||
PChar(ResData) := PChar(FResDir) + SizeOf(TIconHeader);
|
||||
ResList := FExeImage.FCursorResources.List;
|
||||
for I := 0 to Cnt - 1 do
|
||||
begin
|
||||
ResOrd := ResData.wNameOrdinal;
|
||||
for J := 0 to ResList.Count - 1 do
|
||||
begin
|
||||
if ResOrd = ResList[J].FDirEntry.Name then
|
||||
begin
|
||||
CursorResource := ResList[J] as TCursorResEntry;
|
||||
CursorResource.FResInfo := ResData;
|
||||
FList.Add(CursorResource);
|
||||
end;
|
||||
end;
|
||||
Inc(ResData);
|
||||
end;
|
||||
end;
|
||||
Result := FList;
|
||||
end;
|
||||
|
||||
end.
|
235
programs/develop/fp/exe2kos/exetypes.pp
Normal file
235
programs/develop/fp/exe2kos/exetypes.pp
Normal file
@ -0,0 +1,235 @@
|
||||
unit EXETypes;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
IMAGE_DOS_SIGNATURE = $5A4D; { MZ }
|
||||
IMAGE_OS2_SIGNATURE = $454E; { NE }
|
||||
IMAGE_OS2_SIGNATURE_LE = $454C; { LE }
|
||||
IMAGE_VXD_SIGNATURE = $454C; { LE }
|
||||
IMAGE_NT_SIGNATURE = $00004550; { PE00 }
|
||||
|
||||
IMAGE_SIZEOF_SHORT_NAME = 8;
|
||||
IMAGE_SIZEOF_SECTION_HEADER = 40;
|
||||
IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
|
||||
IMAGE_RESOURCE_NAME_IS_STRING = $80000000;
|
||||
IMAGE_RESOURCE_DATA_IS_DIRECTORY = $80000000;
|
||||
IMAGE_OFFSET_STRIP_HIGH = $7FFFFFFF;
|
||||
|
||||
type
|
||||
PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
|
||||
IMAGE_DOS_HEADER = packed record { DOS .EXE header }
|
||||
e_magic : WORD; { Magic number }
|
||||
e_cblp : WORD; { Bytes on last page of file }
|
||||
e_cp : WORD; { Pages in file }
|
||||
e_crlc : WORD; { Relocations }
|
||||
e_cparhdr : WORD; { Size of header in paragraphs }
|
||||
e_minalloc : WORD; { Minimum extra paragraphs needed }
|
||||
e_maxalloc : WORD; { Maximum extra paragraphs needed }
|
||||
e_ss : WORD; { Initial (relative) SS value }
|
||||
e_sp : WORD; { Initial SP value }
|
||||
e_csum : WORD; { Checksum }
|
||||
e_ip : WORD; { Initial IP value }
|
||||
e_cs : WORD; { Initial (relative) CS value }
|
||||
e_lfarlc : WORD; { File address of relocation table }
|
||||
e_ovno : WORD; { Overlay number }
|
||||
e_res : packed array [0..3] of WORD; { Reserved words }
|
||||
e_oemid : WORD; { OEM identifier (for e_oeminfo) }
|
||||
e_oeminfo : WORD; { OEM information; e_oemid specific }
|
||||
e_res2 : packed array [0..9] of WORD; { Reserved words }
|
||||
e_lfanew : Longint; { File address of new exe header }
|
||||
end;
|
||||
|
||||
PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER;
|
||||
IMAGE_FILE_HEADER = packed record
|
||||
Machine : WORD;
|
||||
NumberOfSections : WORD;
|
||||
TimeDateStamp : DWORD;
|
||||
PointerToSymbolTable : DWORD;
|
||||
NumberOfSymbols : DWORD;
|
||||
SizeOfOptionalHeader : WORD;
|
||||
Characteristics : WORD;
|
||||
end;
|
||||
|
||||
PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;
|
||||
IMAGE_DATA_DIRECTORY = packed record
|
||||
VirtualAddress : DWORD;
|
||||
Size : DWORD;
|
||||
end;
|
||||
|
||||
PIMAGE_OPTIONAL_HEADER = ^IMAGE_OPTIONAL_HEADER;
|
||||
IMAGE_OPTIONAL_HEADER = packed record
|
||||
{ Standard fields. }
|
||||
Magic : WORD;
|
||||
MajorLinkerVersion : Byte;
|
||||
MinorLinkerVersion : Byte;
|
||||
SizeOfCode : DWORD;
|
||||
SizeOfInitializedData : DWORD;
|
||||
SizeOfUninitializedData : DWORD;
|
||||
AddressOfEntryPoint : DWORD;
|
||||
BaseOfCode : DWORD;
|
||||
BaseOfData : DWORD;
|
||||
{ NT additional fields. }
|
||||
ImageBase : DWORD;
|
||||
SectionAlignment : DWORD;
|
||||
FileAlignment : DWORD;
|
||||
MajorOperatingSystemVersion : WORD;
|
||||
MinorOperatingSystemVersion : WORD;
|
||||
MajorImageVersion : WORD;
|
||||
MinorImageVersion : WORD;
|
||||
MajorSubsystemVersion : WORD;
|
||||
MinorSubsystemVersion : WORD;
|
||||
Reserved1 : DWORD;
|
||||
SizeOfImage : DWORD;
|
||||
SizeOfHeaders : DWORD;
|
||||
CheckSum : DWORD;
|
||||
Subsystem : WORD;
|
||||
DllCharacteristics : WORD;
|
||||
SizeOfStackReserve : DWORD;
|
||||
SizeOfStackCommit : DWORD;
|
||||
SizeOfHeapReserve : DWORD;
|
||||
SizeOfHeapCommit : DWORD;
|
||||
LoaderFlags : DWORD;
|
||||
NumberOfRvaAndSizes : DWORD;
|
||||
DataDirectory : packed array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY;
|
||||
end;
|
||||
|
||||
PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;
|
||||
IMAGE_SECTION_HEADER = packed record
|
||||
Name : packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char;
|
||||
PhysicalAddress : DWORD; // or VirtualSize (union);
|
||||
VirtualAddress : DWORD;
|
||||
SizeOfRawData : DWORD;
|
||||
PointerToRawData : DWORD;
|
||||
PointerToRelocations : DWORD;
|
||||
PointerToLinenumbers : DWORD;
|
||||
NumberOfRelocations : WORD;
|
||||
NumberOfLinenumbers : WORD;
|
||||
Characteristics : DWORD;
|
||||
end;
|
||||
|
||||
PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
|
||||
IMAGE_NT_HEADERS = packed record
|
||||
Signature : DWORD;
|
||||
FileHeader : IMAGE_FILE_HEADER;
|
||||
OptionalHeader : IMAGE_OPTIONAL_HEADER;
|
||||
end;
|
||||
|
||||
{ Resources }
|
||||
|
||||
PIMAGE_RESOURCE_DIRECTORY = ^IMAGE_RESOURCE_DIRECTORY;
|
||||
IMAGE_RESOURCE_DIRECTORY = packed record
|
||||
Characteristics : DWORD;
|
||||
TimeDateStamp : DWORD;
|
||||
MajorVersion : WORD;
|
||||
MinorVersion : WORD;
|
||||
NumberOfNamedEntries : WORD;
|
||||
NumberOfIdEntries : WORD;
|
||||
end;
|
||||
|
||||
PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^IMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY = packed record
|
||||
Name: DWORD; // Or ID: Word (Union)
|
||||
OffsetToData: DWORD;
|
||||
end;
|
||||
|
||||
PIMAGE_RESOURCE_DATA_ENTRY = ^IMAGE_RESOURCE_DATA_ENTRY;
|
||||
IMAGE_RESOURCE_DATA_ENTRY = packed record
|
||||
OffsetToData : DWORD;
|
||||
Size : DWORD;
|
||||
CodePage : DWORD;
|
||||
Reserved : DWORD;
|
||||
end;
|
||||
|
||||
PIMAGE_RESOURCE_DIR_STRING_U = ^IMAGE_RESOURCE_DIR_STRING_U;
|
||||
IMAGE_RESOURCE_DIR_STRING_U = packed record
|
||||
Length : WORD;
|
||||
NameString : array [0..0] of WCHAR;
|
||||
end;
|
||||
|
||||
{
|
||||
/* Predefined resource types */
|
||||
#define RT_NEWRESOURCE 0x2000
|
||||
#define RT_ERROR 0x7fff
|
||||
#define RT_CURSOR 1
|
||||
#define RT_BITMAP 2
|
||||
#define RT_ICON 3
|
||||
#define RT_MENU 4
|
||||
#define RT_DIALOG 5
|
||||
#define RT_STRING 6
|
||||
#define RT_FONTDIR 7
|
||||
#define RT_FONT 8
|
||||
#define RT_ACCELERATORS 9
|
||||
#define RT_RCDATA 10
|
||||
#define RT_MESSAGETABLE 11
|
||||
#define RT_GROUP_CURSOR 12
|
||||
#define RT_GROUP_ICON 14
|
||||
#define RT_VERSION 16
|
||||
#define RT_NEWBITMAP (RT_BITMAP|RT_NEWRESOURCE)
|
||||
#define RT_NEWMENU (RT_MENU|RT_NEWRESOURCE)
|
||||
#define RT_NEWDIALOG (RT_DIALOG|RT_NEWRESOURCE)
|
||||
|
||||
}
|
||||
|
||||
type
|
||||
TResourceType = (
|
||||
rtUnknown0,
|
||||
rtCursorEntry,
|
||||
rtBitmap,
|
||||
rtIconEntry,
|
||||
rtMenu,
|
||||
rtDialog,
|
||||
rtString,
|
||||
rtFontDir,
|
||||
rtFont,
|
||||
rtAccelerators,
|
||||
rtRCData,
|
||||
rtMessageTable,
|
||||
rtCursor,
|
||||
rtUnknown13,
|
||||
rtIcon,
|
||||
rtUnknown15,
|
||||
rtVersion);
|
||||
|
||||
{ Resource Type Constants }
|
||||
|
||||
const
|
||||
StringsPerBlock = 16;
|
||||
|
||||
{ Resource Related Structures from RESFMT.TXT in WIN32 SDK }
|
||||
|
||||
type
|
||||
|
||||
PIconHeader = ^TIconHeader;
|
||||
TIconHeader = packed record
|
||||
wReserved: Word; { Currently zero }
|
||||
wType: Word; { 1 for icons }
|
||||
wCount: Word; { Number of components }
|
||||
end;
|
||||
|
||||
PIconResInfo = ^TIconResInfo;
|
||||
TIconResInfo = packed record
|
||||
bWidth: Byte;
|
||||
bHeight: Byte;
|
||||
bColorCount: Byte;
|
||||
bReserved: Byte;
|
||||
wPlanes: Word;
|
||||
wBitCount: Word;
|
||||
lBytesInRes: DWORD;
|
||||
wNameOrdinal: Word; { Points to component }
|
||||
end;
|
||||
|
||||
PCursorResInfo = ^TCursorResInfo;
|
||||
TCursorResInfo = packed record
|
||||
wWidth: Word;
|
||||
wHeight: Word;
|
||||
wPlanes: Word;
|
||||
wBitCount: Word;
|
||||
lBytesInRes: DWORD;
|
||||
wNameOrdinal: Word; { Points to component }
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
23
programs/develop/fp/exe2kos/kostypes.pp
Normal file
23
programs/develop/fp/exe2kos/kostypes.pp
Normal file
@ -0,0 +1,23 @@
|
||||
unit KOSTypes;
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
TKosSign = array[0..7] of Byte;
|
||||
TKosHeader = packed record
|
||||
sign : TKOSSign;
|
||||
version: DWord;
|
||||
start : DWord;
|
||||
size : DWord;
|
||||
memory : DWord;
|
||||
stack : DWord;
|
||||
args : DWord;
|
||||
path : DWord;
|
||||
end;
|
||||
|
||||
const
|
||||
KOS_SIGN: TKOSSign = ($4D, $45, $4E, $55, $45, $54, $30, $31);
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
3
programs/develop/fp/readme-ru.txt
Normal file
3
programs/develop/fp/readme-ru.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Codepage: koi8-r
|
||||
|
||||
Комментарии будут позже.
|
9
programs/develop/fp/rtl/_defines.inc
Normal file
9
programs/develop/fp/rtl/_defines.inc
Normal file
@ -0,0 +1,9 @@
|
||||
{$undef mswindows}
|
||||
{$undef windows}
|
||||
{$undef Windows}
|
||||
{$undef win32}
|
||||
{$undef os2}
|
||||
{$undef linux}
|
||||
|
||||
{$define EMULATOR}
|
||||
{$undef debug_mt}
|
20
programs/develop/fp/rtl/build.bat
Normal file
20
programs/develop/fp/rtl/build.bat
Normal file
@ -0,0 +1,20 @@
|
||||
@echo off
|
||||
|
||||
set FPRTL={path to original freepascal rtl source code, example ... \fp\src\rtl}
|
||||
set INCS=-Fi%FPRTL%\inc;%FPRTL%\i386;%FPRTL%\objpas;%FPRTL%\objpas\sysutils;%FPRTL%\objpas\classes
|
||||
set UNTS=-Fu%FPRTL%\inc;%FPRTL%\i386;%FPRTL%\objpas
|
||||
set FPCARGS=-Twin32 -Se5 -Sg -n -O3pPENTIUM3 -CfSSE -di386 -FU..\units %INCS% %UNTS%
|
||||
|
||||
fpc system.pp -Us %FPCARGS%
|
||||
if errorlevel 1 goto error
|
||||
|
||||
fpc %FPRTL%\objpas\objpas.pp %FPCARGS%
|
||||
if errorlevel 1 goto error
|
||||
|
||||
fpc buildrtl.pp %FPCARGS%
|
||||
if errorlevel 0 goto end
|
||||
|
||||
:error
|
||||
echo An error occured while building RTL
|
||||
|
||||
:end
|
20
programs/develop/fp/rtl/buildrtl.pp
Normal file
20
programs/develop/fp/rtl/buildrtl.pp
Normal file
@ -0,0 +1,20 @@
|
||||
unit buildrtl;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
sysinitpas, {sysinitcyg, sysinitgprof,}
|
||||
ctypes, strings,
|
||||
lineinfo, lnfodwrf, heaptrc, matrix,
|
||||
{windows, winsock, winsock2, initc, cmem, dynlibs, signals,}
|
||||
dos, crt, objects{, messages,
|
||||
rtlconsts, sysconst}, sysutils{, math, types,
|
||||
strutils, dateutils, varutils, variants, typinfo, fgl}, classes{,
|
||||
convutils, stdconvs, cpu, mmx, charset, ucomplex, getopts,
|
||||
winevent, sockets, printer,
|
||||
video, mouse, keyboard, fmtbcd,
|
||||
winsysut, sharemem};
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
26
programs/develop/fp/rtl/classes.pp
Normal file
26
programs/develop/fp/rtl/classes.pp
Normal file
@ -0,0 +1,26 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit Classes;
|
||||
|
||||
{$i _defines.inc}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
RTLConsts, SysUtils, Types, TypInfo;
|
||||
|
||||
{$i classesh.inc}
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
SysConst;
|
||||
|
||||
{ OS - independent class implementations are in /inc directory. }
|
||||
{$i classes.inc}
|
||||
|
||||
initialization
|
||||
CommonInit;
|
||||
finalization
|
||||
CommonCleanup;
|
||||
end.
|
7
programs/develop/fp/rtl/crt.pp
Normal file
7
programs/develop/fp/rtl/crt.pp
Normal file
@ -0,0 +1,7 @@
|
||||
unit Crt;
|
||||
|
||||
interface
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
9
programs/develop/fp/rtl/dos.pp
Normal file
9
programs/develop/fp/rtl/dos.pp
Normal file
@ -0,0 +1,9 @@
|
||||
unit Dos;
|
||||
|
||||
interface
|
||||
|
||||
{$i filerec.inc}
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
708
programs/develop/fp/rtl/kos.inc
Normal file
708
programs/develop/fp/rtl/kos.inc
Normal file
@ -0,0 +1,708 @@
|
||||
{cp866}
|
||||
|
||||
{ User interface }
|
||||
procedure kos_definewindow(x, y, w, h: Word; style, header, clframe: DWord); assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
movl %eax, %ebx
|
||||
xchgl %edx, %ecx
|
||||
movl header, %esi
|
||||
shll $16, %ebx
|
||||
shll $16, %ecx
|
||||
movl clframe, %edi
|
||||
movw %dx, %bx
|
||||
movw h, %cx
|
||||
xorl %eax, %eax
|
||||
movl style, %edx
|
||||
decl %ebx {㬥ìè¨âì è¨à¨ã 1}
|
||||
decl %ecx {㬥ìè¨âì ¢ëá®âã 1}
|
||||
int $0x40
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
procedure kos_movewindow(x, y, w, h: DWord); assembler; register;
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %esi
|
||||
movl %eax, %ebx
|
||||
xchgl %ecx, %edx
|
||||
movl $67, %eax
|
||||
movl h, %esi
|
||||
decl %edx {㬥ìè¨âì è¨à¨ã 1}
|
||||
decl %esi {㬥ìè¨âì ¢ëá®âã 1}
|
||||
int $0x40
|
||||
popl %esi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
function kos_getkey(): DWord; assembler; register;
|
||||
asm
|
||||
movl $2, %eax
|
||||
int $0x40
|
||||
end;
|
||||
|
||||
function kos_getevent(wait: Boolean = True): DWord; assembler; register;
|
||||
asm
|
||||
andl $1, %eax
|
||||
xorb $1, %al
|
||||
addl $10, %eax
|
||||
int $0x40
|
||||
end;
|
||||
|
||||
function kos_waitevent(timeout: DWord): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $23, %ebx
|
||||
xchgl %eax, %ebx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_getbutton(): DWord; assembler; register;
|
||||
asm
|
||||
movl $17, %eax
|
||||
int $0x40
|
||||
shrl $8, %eax
|
||||
andl $0xFF, %eax
|
||||
end;
|
||||
|
||||
function kos_getmousepos(): TKosPoint; assembler; register;
|
||||
{@return: x*65536 + y}
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %eax
|
||||
movl $37, %eax
|
||||
xorl %ebx, %ebx
|
||||
int $0x40
|
||||
movswl %ax, %ecx
|
||||
popl %ebx
|
||||
shrl $16, %eax
|
||||
movl %ecx, TKosPoint.Y(%ebx)
|
||||
movl %eax, TKosPoint.X(%ebx)
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
function kos_getmousewinpos(): TKosPoint; assembler; register;
|
||||
{@return: x*65536 + y}
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %eax
|
||||
movl $37, %eax
|
||||
movl $1, %ebx
|
||||
int $0x40
|
||||
movswl %ax, %ecx
|
||||
popl %ebx
|
||||
shrl $16, %eax
|
||||
movl %ecx, TKosPoint.Y(%ebx)
|
||||
movl %eax, TKosPoint.X(%ebx)
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
function kos_getmousebuttons(): DWord; assembler; register;
|
||||
{@return:
|
||||
¡¨â 0 ãáâ ®¢«¥ = «¥¢ ï ª®¯ª ¦ â
|
||||
¡¨â 1 ãáâ ®¢«¥ = ¯à ¢ ï ª®¯ª ¦ â
|
||||
¡¨â 2 ãáâ ®¢«¥ = á।ïï ª®¯ª ¦ â
|
||||
¡¨â 3 ãáâ ®¢«¥ = 4-ï ª®¯ª ¦ â
|
||||
¡¨â 4 ãáâ ®¢«¥ = 5-ï ª®¯ª ¦ â }
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $37, %eax
|
||||
movl $2, %ebx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
procedure kos_maskevents(mask: DWord); assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
xchgl %eax, %ebx
|
||||
movl $40, %eax
|
||||
int $0x40
|
||||
xchgl %eax, %ebx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
procedure kos_setcaption(caption: PChar); assembler; register;
|
||||
asm
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
xchgl %eax, %ecx
|
||||
movl $1, %ebx
|
||||
movl $71, %eax
|
||||
int $0x40
|
||||
xchgl %eax, %ecx
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
end;
|
||||
|
||||
|
||||
{ Graphics }
|
||||
|
||||
procedure kos_begindraw(); assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $12, %eax
|
||||
movl $1, %ebx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
procedure kos_enddraw(); assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $12, %eax
|
||||
movl $2, %ebx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
procedure kos_putpixel(x, y: Word; color: DWord); assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl %eax, %ebx
|
||||
xchgl %edx, %ecx
|
||||
movl $1, %eax
|
||||
int $0x40
|
||||
xchgl %edx, %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
procedure kos_drawtext(x, y: Word; text: String; flags, bgcolor: DWord); assembler; register;
|
||||
label nobg;
|
||||
asm
|
||||
pusha
|
||||
shll $16, %eax
|
||||
pushl %ecx
|
||||
movl flags, %ecx {ä« £¨, 梥â}
|
||||
movl bgcolor, %edi
|
||||
movw %dx, %ax
|
||||
andl $0x7FFFFFFF, %ecx
|
||||
btl $31, %edi
|
||||
jnc nobg
|
||||
orl $0x40000000, %ecx
|
||||
nobg:
|
||||
popl %edx
|
||||
movl %eax, %ebx {ª®®à¤¨ âë}
|
||||
movzbl (%edx), %esi {¤«¨ áâப¨}
|
||||
movl $4, %eax {®¬¥à äãªæ¨¨}
|
||||
incl %edx {㪠§ ⥫ì áâபã}
|
||||
andl $0xFFFFFF, %edi
|
||||
int $0x40
|
||||
popa
|
||||
end;
|
||||
|
||||
procedure kos_drawrect(x, y, w, h: Word; color: DWord); assembler; register;
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
movl %eax, %ebx
|
||||
xchgl %edx, %ecx
|
||||
shll $16, %ebx
|
||||
shll $16, %ecx
|
||||
movl $13, %eax
|
||||
movw %dx, %bx
|
||||
movw h, %cx
|
||||
movl color, %edx
|
||||
int $0x40
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
procedure kos_drawline(x1, y1, x2, y2: Word; color: DWord = $000000); assembler; register;
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
|
||||
xchgl %eax, %ecx
|
||||
xchgl %ecx, %edx
|
||||
movl color, %ebx
|
||||
{eax - x2, ebx - color, ecx - y1, edx - x1}
|
||||
shll $16, %ecx
|
||||
shll $16, %edx
|
||||
movw %ax, %dx
|
||||
movw y2, %cx
|
||||
movl $38, %eax
|
||||
xchgl %ebx, %edx
|
||||
int $0x40
|
||||
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
procedure kos_drawimage(x, y, w, h, depth: DWord; image: Pointer; palette: Pointer; xoffset: DWord); assembler; register;
|
||||
asm
|
||||
pusha
|
||||
shll $16, %eax
|
||||
shll $16, %ecx
|
||||
orl %eax, %edx
|
||||
orl h, %ecx
|
||||
movl depth, %esi
|
||||
movl image, %ebx
|
||||
movl palette, %edi
|
||||
movl xoffset, %ebp
|
||||
movl $65, %eax
|
||||
int $0x40
|
||||
popa
|
||||
end;
|
||||
|
||||
procedure kos_drawimage24(x, y, w, h: DWord; image: Pointer); assembler; register;
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
shll $16, %eax
|
||||
shll $16, %ecx
|
||||
orl %eax, %edx
|
||||
orl h, %ecx
|
||||
movl image, %ebx
|
||||
movl $7, %eax
|
||||
int $0x40
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
|
||||
{ Work with system }
|
||||
|
||||
{ Work with system - System services }
|
||||
|
||||
function kos_killthread(tid: TThreadID): Boolean; assembler; register;
|
||||
asm
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
movl $18, %ecx
|
||||
movl $18, %ebx
|
||||
xchgl %eax, %ecx
|
||||
int $0x40
|
||||
andl $1, %eax
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
xorb $1, %al
|
||||
end;
|
||||
|
||||
procedure kos_setactivewindow(slot: TThreadSlot); assembler; register;
|
||||
asm
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
movl $18, %ecx
|
||||
movl $3, %ebx
|
||||
xchgl %eax, %ecx
|
||||
int $0x40
|
||||
xchgl %eax, %ecx
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
end;
|
||||
|
||||
{$ifdef EMULATOR}
|
||||
function kos_getthreadslot(tid: TThreadID): TThreadSlot;
|
||||
var
|
||||
ThreadInfo: TKosThreadInfo;
|
||||
HighThreadSlot: TThreadSlot;
|
||||
begin
|
||||
Result := 0;
|
||||
repeat
|
||||
Inc(Result);
|
||||
HighThreadSlot := kos_threadinfo(@ThreadInfo, Result);
|
||||
until (Result > HighThreadSlot) or (ThreadInfo.ThreadID = tid);
|
||||
end;
|
||||
|
||||
{$else}
|
||||
|
||||
function kos_getthreadslot(tid: TThreadID): TThreadSlot; assembler; register;
|
||||
asm
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
movl $18, %ecx
|
||||
movl $21, %ebx
|
||||
xchgl %eax, %ecx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{ Work with system - Set system parameters }
|
||||
|
||||
procedure kos_enablepci(); assembler; register;
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
movl $21, %eax
|
||||
movl $12, %ebx
|
||||
movl $1, %ecx
|
||||
int $0x40
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
{ Work with system - Internal system services }
|
||||
|
||||
procedure kos_switchthread(); assembler; register;
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
movl $68, %eax
|
||||
movl $1, %ebx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
function kos_initheap(): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $68, %eax
|
||||
movl $11, %ebx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_alloc(size: DWord): Pointer; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
movl %eax, %ecx
|
||||
movl $68, %eax
|
||||
movl $12, %ebx
|
||||
int $0x40
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_free(ptr: Pointer): Boolean; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
movl %eax, %ecx
|
||||
movl $68, %eax
|
||||
movl $13, %ebx
|
||||
int $0x40
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_loaddriver(name: PChar): THandle; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
movl %eax, %ecx
|
||||
movl $68, %eax
|
||||
movl $16, %ebx
|
||||
int $0x40
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
|
||||
{ Processes and threads }
|
||||
|
||||
function kos_threadinfo(info: PKosThreadInfo; slot: TThreadSlot): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl %eax, %ebx
|
||||
xchgl %edx, %ecx
|
||||
movl $9, %eax
|
||||
int $0x40
|
||||
xchgl %edx, %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_newthread(entry, stack: Pointer): TThreadID; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
movl $1, %ebx
|
||||
movl %eax, %ecx
|
||||
movl $51, %eax
|
||||
int $0x40
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
procedure kos_initipc(ipc: PKosIPC; size: DWord); assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
movl $60, %ecx
|
||||
movl $1, %ebx
|
||||
xchgl %eax, %ecx
|
||||
int $0x40
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_sendmsg(tid: TThreadID; msg: Pointer; size: DWord): DWord; assembler; register;
|
||||
{@return:
|
||||
0 - ãᯥè®
|
||||
1 - ¯à¨ñ¬¨ª ¥ ®¯à¥¤¥«¨« ¡ãä¥à ¤«ï IPC-á®®¡é¥¨©
|
||||
(¬®¦¥â ¡ëâì, ¥éñ ¥ ãᯥ«, ¬®¦¥â ¡ëâì, íâ® ¥ â®â ¯®â®ª, ª®â®àë© ã¦¥)
|
||||
2 - ¯à¨ñ¬¨ª § ¡«®ª¨à®¢ « IPC-¡ãä¥à; ¯®¯à®¡ã©â¥ ¥¬®£® ¯®¤®¦¤ âì
|
||||
3 - ¯¥à¥¯®«¥¨¥ IPC-¡ãä¥à ¯à¨ñ¬¨ª
|
||||
4 - ¯à®æ¥áá /¯®â®ª á â ª¨¬ PID ¥ áãé¥áâ¢ã¥â}
|
||||
asm
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
movl $60, %esi
|
||||
movl $2, %ebx
|
||||
xchgl %ecx, %esi
|
||||
xchgl %eax, %ecx
|
||||
int $0x40
|
||||
xchgl %ecx, %esi
|
||||
popl %ebx
|
||||
popl %esi
|
||||
end;
|
||||
|
||||
function kos_resizemem(size: DWord): Boolean; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
movl %eax, %ecx
|
||||
movl $64, %eax
|
||||
movl $1, %ebx
|
||||
int $0x40
|
||||
xorb $1, %al
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
|
||||
{ File system }
|
||||
{ File system - Work with the current folder }
|
||||
|
||||
procedure kos_setdir(path: PChar); assembler; register;
|
||||
asm
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
movl $30, %ecx
|
||||
movl $1, %ebx
|
||||
xchgl %eax, %ecx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
end;
|
||||
|
||||
function kos_getdir(path: PChar; size: DWord): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
movl $30, %ecx
|
||||
movl $2, %ebx
|
||||
xchgl %eax, %ecx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
end;
|
||||
|
||||
{ File system - Work with file system with long names support }
|
||||
|
||||
function kos_readfile(kosfile: PKosFile; var readed: Longint): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $70, %ebx
|
||||
xchgl %eax, %ebx
|
||||
movl $0, (%ebx)
|
||||
int $0x40
|
||||
movl %ebx, (%edx)
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_rewritefile(kosfile: PKosFile; var writed: Longint): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $70, %ebx
|
||||
xchgl %eax, %ebx
|
||||
movl $2, (%ebx)
|
||||
int $0x40
|
||||
movl %ebx, (%edx)
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_writefile(kosfile: PKosFile; var writed: Longint): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $70, %ebx
|
||||
xchgl %eax, %ebx
|
||||
movl $3, (%ebx)
|
||||
int $0x40
|
||||
movl %ebx, (%edx)
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_fileinfo(kosfile: PKosFile): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $70, %ebx
|
||||
xchgl %eax, %ebx
|
||||
movl $5, (%ebx)
|
||||
int $0x40
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
|
||||
{ Work with hardware }
|
||||
|
||||
function kos_readport(index: DWord): DWord; assembler; register;
|
||||
label ok, exit;
|
||||
asm
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
xchgl %eax, %ecx {index}
|
||||
movl $43, %eax
|
||||
orl $0x80000000, %ecx {index}
|
||||
int $0x40
|
||||
orl %eax, %eax
|
||||
jzl ok
|
||||
movl $-1, %eax
|
||||
jmp exit
|
||||
ok:
|
||||
movl %ebx, %eax
|
||||
exit:
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
end;
|
||||
|
||||
procedure kos_writeport(index, value: DWord); assembler; register;
|
||||
asm
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
xchgl %edx, %ebx {value}
|
||||
xchgl %eax, %ecx {index}
|
||||
movl $43, %eax
|
||||
int $0x40
|
||||
xchgl %edx, %ebx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
end;
|
||||
|
||||
function kos_reserveport(port: DWord): Boolean; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
movl %eax, %ecx {port}
|
||||
movl $46, %eax
|
||||
movl %ecx, %edx {port}
|
||||
xorl %ebx, %ebx
|
||||
int $0x40
|
||||
xorb $1, %al
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
{ Work with hardware - Low-level access to PCI}
|
||||
|
||||
function kos_lastpcibus(): Byte; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl $62, %eax
|
||||
movl $1, %ebx
|
||||
int $0x40
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_readpcib(bus, dev, func, reg: Byte): Byte; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
shlb $3, %dl {dev}
|
||||
movb %al, %bh {bus}
|
||||
shlw $8, %cx {func}
|
||||
movb $4, %bl
|
||||
movb reg, %cl {func}
|
||||
andb $7, %ch {func}
|
||||
movl $62, %eax
|
||||
orb %dl, %ch {dev/func}
|
||||
int $0x40
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_readpciw(bus, dev, func, reg: Byte): Word; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
shlb $3, %dl {dev}
|
||||
movb %al, %bh {bus}
|
||||
shlw $8, %cx {func}
|
||||
movb $5, %bl
|
||||
movb reg, %cl {reg}
|
||||
andb $7, %ch {func}
|
||||
movl $62, %eax
|
||||
orb %dl, %ch {dev/func}
|
||||
int $0x40
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
function kos_readpcid(bus, dev, func, reg: Byte): DWord; assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
shlb $3, %dl {dev}
|
||||
movb %al, %bh {bus}
|
||||
shlw $8, %cx {func}
|
||||
movb $6, %bl
|
||||
movb reg, %cl {reg}
|
||||
andb $7, %ch {func}
|
||||
movl $62, %eax
|
||||
orb %dl, %ch {dev/func}
|
||||
int $0x40
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
|
||||
{ Other }
|
||||
procedure kos_delay(ms: DWord); assembler; register;
|
||||
asm
|
||||
pushl %ebx
|
||||
movl %eax, %ebx
|
||||
movl $5, %eax
|
||||
int $0x40
|
||||
popl %ebx
|
||||
end;
|
115
programs/develop/fp/rtl/kos_def.inc
Normal file
115
programs/develop/fp/rtl/kos_def.inc
Normal file
@ -0,0 +1,115 @@
|
||||
{Ž¯à¥¤¥«¥¨ï, ª®áâ âë}
|
||||
|
||||
const
|
||||
{‘¨áâ¥¬ë¥ á®¡ëâ¨ï}
|
||||
SE_PAINT = 1;
|
||||
SE_KEYBOARD = 2;
|
||||
SE_BUTTON = 3;
|
||||
SE_MOUSE = 6;
|
||||
SE_IPC = 7;
|
||||
|
||||
{Œ ᪨ ᮡë⨩}
|
||||
ME_PAINT = 1 shl (SE_PAINT - 1);
|
||||
ME_KEYBOARD = 1 shl (SE_KEYBOARD - 1);
|
||||
ME_BUTTON = 1 shl (SE_BUTTON - 1);
|
||||
ME_MOUSE = 1 shl (SE_MOUSE - 1);
|
||||
ME_IPC = 1 shl (SE_IPC - 1);
|
||||
|
||||
{Š®¤ë ª« ¢¨è}
|
||||
VK_LBUTTON = 1;
|
||||
VK_RBUTTON = 2;
|
||||
VK_CANCEL = 3;
|
||||
VK_MBUTTON = 4;
|
||||
VK_BACK = 8;
|
||||
VK_TAB = 9;
|
||||
VK_CLEAR = 12;
|
||||
VK_RETURN = 13;
|
||||
VK_SHIFT = 16;
|
||||
VK_CONTROL = 17;
|
||||
VK_MENU = 18;
|
||||
VK_PAUSE = 19;
|
||||
VK_CAPITAL = 20;
|
||||
VK_ESCAPE = 27;
|
||||
VK_SPACE = 32;
|
||||
VK_PRIOR = 33;
|
||||
VK_NEXT = 34;
|
||||
VK_END = 35;
|
||||
VK_HOME = 36;
|
||||
VK_LEFT = 37;
|
||||
VK_UP = 38;
|
||||
VK_RIGHT = 39;
|
||||
VK_DOWN = 40;
|
||||
VK_SELECT = 41;
|
||||
VK_PRINT = 42;
|
||||
VK_EXECUTE = 43;
|
||||
VK_SNAPSHOT = 44;
|
||||
VK_INSERT = 45;
|
||||
VK_DELETE = 46;
|
||||
VK_HELP = 47;
|
||||
VK_0 = 48;
|
||||
VK_1 = 49;
|
||||
VK_2 = 50;
|
||||
VK_3 = 51;
|
||||
VK_4 = 52;
|
||||
VK_5 = 53;
|
||||
VK_6 = 54;
|
||||
VK_7 = 55;
|
||||
VK_8 = 56;
|
||||
VK_9 = 57;
|
||||
VK_A = 65;
|
||||
VK_B = 66;
|
||||
VK_C = 67;
|
||||
VK_D = 68;
|
||||
VK_E = 69;
|
||||
VK_F = 70;
|
||||
VK_G = 71;
|
||||
VK_H = 72;
|
||||
VK_I = 73;
|
||||
VK_J = 74;
|
||||
VK_K = 75;
|
||||
VK_L = 76;
|
||||
VK_M = 77;
|
||||
VK_N = 78;
|
||||
VK_O = 79;
|
||||
VK_P = 80;
|
||||
VK_Q = 81;
|
||||
VK_R = 82;
|
||||
VK_S = 83;
|
||||
VK_T = 84;
|
||||
VK_U = 85;
|
||||
VK_V = 86;
|
||||
VK_W = 87;
|
||||
VK_X = 88;
|
||||
VK_Y = 89;
|
||||
VK_Z = 90;
|
||||
VK_LWIN = 91;
|
||||
VK_RWIN = 92;
|
||||
VK_APPS = 93;
|
||||
VK_NUMPAD0 = 96;
|
||||
VK_NUMPAD1 = 97;
|
||||
VK_NUMPAD2 = 98;
|
||||
VK_NUMPAD3 = 99;
|
||||
VK_NUMPAD4 = 100;
|
||||
VK_NUMPAD5 = 101;
|
||||
VK_NUMPAD6 = 102;
|
||||
VK_NUMPAD7 = 103;
|
||||
VK_NUMPAD8 = 104;
|
||||
VK_NUMPAD9 = 105;
|
||||
VK_MULTIPLY = 106;
|
||||
VK_ADD = 107;
|
||||
VK_SEPARATOR = 108;
|
||||
VK_SUBTRACT = 109;
|
||||
VK_DECIMAL = 110;
|
||||
VK_DIVIDE = 111;
|
||||
VK_F1 = 112;
|
||||
VK_F2 = 113;
|
||||
VK_F3 = 114;
|
||||
VK_F4 = 115;
|
||||
VK_F5 = 116;
|
||||
VK_F6 = 117;
|
||||
VK_F7 = 118;
|
||||
VK_F8 = 119;
|
||||
VK_F9 = 120;
|
||||
VK_F10 = 121;
|
||||
VK_F11 = 122;
|
||||
VK_F12 = 123;
|
355
programs/develop/fp/rtl/kos_stdio.inc
Normal file
355
programs/develop/fp/rtl/kos_stdio.inc
Normal file
@ -0,0 +1,355 @@
|
||||
{}
|
||||
|
||||
procedure OpenStdout(var f: TextRec); forward;
|
||||
procedure WriteStdout(var f: TextRec); forward;
|
||||
procedure CloseStdout(var f: TextRec); forward;
|
||||
|
||||
procedure OpenStdin(var f: TextRec); forward;
|
||||
procedure ReadStdin(var f: TextRec); forward;
|
||||
procedure CloseStdin(var f: TextRec); forward;
|
||||
|
||||
|
||||
|
||||
procedure AssignStdout(var f: Text);
|
||||
begin
|
||||
Assign(f, '');
|
||||
TextRec(f).OpenFunc := @OpenStdout;
|
||||
Rewrite(f);
|
||||
end;
|
||||
|
||||
procedure OpenStdout(var f: TextRec);
|
||||
begin
|
||||
TextRec(f).InOutFunc := @WriteStdout;
|
||||
TextRec(f).FlushFunc := @WriteStdout;
|
||||
TextRec(f).CloseFunc := @CloseStdout;
|
||||
end;
|
||||
|
||||
procedure WriteStdout(var f: TextRec);
|
||||
var
|
||||
msg: String;
|
||||
begin
|
||||
msg := StrPas(PChar(f.bufptr));
|
||||
SetLength(msg, f.bufpos);
|
||||
f.bufpos := 0;
|
||||
Konsole.Write(msg);
|
||||
end;
|
||||
|
||||
procedure CloseStdout(var f: TextRec);
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure AssignStdin(var f: Text);
|
||||
begin
|
||||
Assign(f, '');
|
||||
TextRec(f).OpenFunc := @OpenStdin;
|
||||
Reset(f);
|
||||
end;
|
||||
|
||||
procedure OpenStdin(var f: TextRec);
|
||||
begin
|
||||
TextRec(f).InOutFunc := @ReadStdin;
|
||||
TextRec(f).FlushFunc := nil;
|
||||
TextRec(f).CloseFunc := @CloseStdin;
|
||||
end;
|
||||
|
||||
procedure ReadStdin(var f: TextRec);
|
||||
var
|
||||
max, curpos: Longint;
|
||||
c: Longint;
|
||||
begin
|
||||
max := f.bufsize - Length(LineEnding);
|
||||
curpos := 0;
|
||||
repeat
|
||||
c := 13{l4_getc()};
|
||||
case c of
|
||||
13:
|
||||
begin
|
||||
{f.bufptr^[curpos] := LineEnding;}
|
||||
Inc(curpos);
|
||||
f.bufpos := 0;
|
||||
f.bufend := curpos;
|
||||
{l4_putc(Longint(LineEnding));}
|
||||
break;
|
||||
end;
|
||||
32..126: if curpos < max then
|
||||
begin
|
||||
f.bufptr^[curpos] := Char(c);
|
||||
Inc(curpos);
|
||||
{l4_putc(c);}
|
||||
end;
|
||||
end;
|
||||
until False;
|
||||
end;
|
||||
|
||||
procedure CloseStdin(var f: TextRec);
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
{ TKonsole }
|
||||
|
||||
procedure KonsoleThreadMain(Console: PKonsole);
|
||||
{<EFBFBD> ¡®ç¨© 横« ª®á®«¨}
|
||||
var
|
||||
ThreadInfo: TKosThreadInfo;
|
||||
Message: ShortString;
|
||||
Event: DWord;
|
||||
begin
|
||||
kos_maskevents(ME_PAINT or ME_KEYBOARD or ME_IPC);
|
||||
kos_threadinfo(@ThreadInfo);
|
||||
Console^.FThreadSlot := kos_getthreadslot(ThreadInfo.ThreadID);
|
||||
|
||||
kos_initipc(Console^.FIPCBuffer, Console^.FIPCBufferSize);
|
||||
|
||||
{áà §ã ®â®¡à §¨âì ¨ ªâ¨¢¨à®¢ âì ®ª®}
|
||||
Console^.Paint();
|
||||
{$ifndef EMULATOR}
|
||||
kos_setactivewindow(Console^.FThreadSlot);
|
||||
{$endif}
|
||||
|
||||
{£®â®¢ ª ®¡à ¡®âª¥ ᮡë⨩}
|
||||
Console^.FOpened := True;
|
||||
while not Console^.FTerminate do
|
||||
begin
|
||||
Event := kos_getevent();
|
||||
if Console^.FTerminate then
|
||||
{Console^.ProcessMessage('[CONSOLE] Terminate...'#13#10)} else
|
||||
case Event of
|
||||
SE_PAINT: Console^.Paint();
|
||||
SE_KEYBOARD: Console^.ProcessKeyboard(kos_getkey());
|
||||
SE_IPC: while Console^.ReceiveMessage(Message) do Console^.ProcessMessage(Message);
|
||||
end;
|
||||
end;
|
||||
Console^.FOpened := False;
|
||||
end;
|
||||
|
||||
constructor TKonsole.Init(ACaption: String);
|
||||
const
|
||||
IPC_SIZE = 4096;
|
||||
var
|
||||
ThreadInfo: TKosThreadInfo;
|
||||
begin
|
||||
if ACaption <> '' then
|
||||
FCaption := ACaption else
|
||||
begin
|
||||
kos_threadinfo(@ThreadInfo);
|
||||
FCaption := StrPas(ThreadInfo.AppName);
|
||||
end;
|
||||
SetLength(FLines, 1);
|
||||
FLines[0] := ' ';
|
||||
FCursor.X := 1;
|
||||
FCursor.Y := 0;
|
||||
FMaxLines := 150;
|
||||
FTerminate := False;
|
||||
FOpened := False;
|
||||
FIPCBufferSize := SizeOf(TKosIPC) + IPC_SIZE;
|
||||
FIPCBuffer := GetMem(FIPCBufferSize);
|
||||
{FIPCBufferSize := SizeOf(KonsoleIPCBuffer);
|
||||
FIPCBuffer := @KonsoleIPCBuffer;}
|
||||
FIPCBuffer^.Lock := False;
|
||||
FIPCBuffer^.Size := 0;
|
||||
FThreadSlot := -1;
|
||||
FThreadID := BeginThread(TThreadFunc(@KonsoleThreadMain), @Self);
|
||||
if FThreadID <> 0 then
|
||||
while not FOpened do kos_delay(1);
|
||||
end;
|
||||
|
||||
destructor TKonsole.Done();
|
||||
begin
|
||||
FTerminate := True;
|
||||
Self.Write(#0);
|
||||
if FOpened then kos_delay(1);
|
||||
if FOpened then kos_delay(10);
|
||||
if FOpened then kos_delay(20);
|
||||
if FOpened then
|
||||
begin
|
||||
FOpened := False;
|
||||
KillThread(FThreadID);
|
||||
end;
|
||||
FreeMem(FIPCBuffer);
|
||||
SetLength(FLines, 0);
|
||||
end;
|
||||
|
||||
function TKonsole.ReceiveMessage(var Message: ShortString): Boolean;
|
||||
{ˆ§¢«¥çì ¯¥à¢®¥ á®®¡é¥¨¥ ¨§ ¡ãä¥à }
|
||||
var
|
||||
PMsg: PKosMessage;
|
||||
Size: Longword;
|
||||
begin
|
||||
if FIPCBuffer^.Size > 0 then
|
||||
begin
|
||||
FIPCBuffer^.Lock := True;
|
||||
PMsg := Pointer(Longword(FIPCBuffer) + SizeOf(TKosIPC));
|
||||
{TODO: ¯à®¢¥àª PMsg^.SenderID}
|
||||
{Size := PMsg^.Size;
|
||||
Dec(FIPCBuffer^.Size, Size + SizeOf(TKosMessage));
|
||||
if Size > 255 then Size := 255;
|
||||
SetLength(Message, Size);
|
||||
Move(Pointer(Longword(PMsg) + SizeOf(TKosMessage))^, Message[1], Size);
|
||||
if FIPCBuffer^.Size > 0 then
|
||||
Move(Pointer(Longword(PMsg) + SizeOf(TKosMessage) + PMsg^.Size)^, PMsg^, FIPCBuffer^.Size);}
|
||||
|
||||
{XXX}
|
||||
Size := FIPCBuffer^.Size;
|
||||
Dec(FIPCBuffer^.Size, Size);
|
||||
if Size > 255 then Size := 255;
|
||||
SetLength(Message, Size);
|
||||
Move(PMsg^, Message[1], Size);
|
||||
|
||||
Result := True;
|
||||
end else
|
||||
begin
|
||||
Message := '';
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
{FIXME: ¥á«¨ FIPCBuffer^.Size = 0, â® FIPCBuffer^.Lock ¢á¥ à ¢® > 0}
|
||||
FIPCBuffer^.Lock := False;
|
||||
end;
|
||||
|
||||
procedure TKonsole.ProcessMessage(Message: ShortString);
|
||||
{‚뢥á⨠ᮮ¡é¥¨¥ ª®á®«ì}
|
||||
var
|
||||
S: String;
|
||||
LinesCount: Word;
|
||||
CR, LF, W: Word;
|
||||
BottomRow: Boolean = True;
|
||||
begin
|
||||
if Length(Message) < 1 then Exit;
|
||||
|
||||
repeat
|
||||
CR := Pos(#13, Message);
|
||||
LF := Pos(#10, Message);
|
||||
if (CR > 0) and ((CR < LF) or (LF <= 0)) then
|
||||
W := CR else
|
||||
if LF > 0 then
|
||||
W := LF else
|
||||
W := Length(Message) + 1;
|
||||
if W > 0 then
|
||||
begin
|
||||
if W > 1 then
|
||||
begin
|
||||
S := Copy(Message, 1, W - 1);
|
||||
Delete(FLines[FCursor.Y], FCursor.X, Length(FLines[FCursor.Y]) - FCursor.X);
|
||||
Insert(S, FLines[FCursor.Y], FCursor.X);
|
||||
Inc(FCursor.X, Length(S));
|
||||
end;
|
||||
Delete(Message, 1, W);
|
||||
if W = CR then
|
||||
{¯¥à¥¢®¤ ª®à¥âª¨ ¢ ç «® áâப¨}
|
||||
FCursor.X := 1 else
|
||||
if W = LF then
|
||||
begin
|
||||
{¯¥à¥¢®¤ ª®à¥âª¨ á«¥¤ãîéãî áâபã}
|
||||
BottomRow := False;
|
||||
Inc(FCursor.Y);
|
||||
LinesCount := Length(FLines);
|
||||
while FCursor.Y >= FMaxLines do Dec(FCursor.Y, FMaxLines);
|
||||
if FCursor.Y < LinesCount then FLines[FCursor.Y] := '';
|
||||
while FCursor.Y >= LinesCount do
|
||||
begin
|
||||
SetLength(FLines, LinesCount + 1);
|
||||
FLines[LinesCount] := '';
|
||||
Inc(LinesCount);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
until Length(Message) <= 0;
|
||||
|
||||
Paint(BottomRow);
|
||||
end;
|
||||
|
||||
procedure TKonsole.ProcessKeyboard(Key: Word);
|
||||
begin
|
||||
FKeyPressed := Key;
|
||||
end;
|
||||
|
||||
function TKonsole.GetRect(): TKosRect;
|
||||
var
|
||||
ThreadInfo: TKosThreadInfo;
|
||||
begin
|
||||
kos_threadinfo(@ThreadInfo, FThreadSlot);
|
||||
Result := ThreadInfo.WindowRect;
|
||||
end;
|
||||
|
||||
function TKonsole.GetKeyPressed(): Word;
|
||||
begin
|
||||
Result := FKeyPressed;
|
||||
FKeyPressed := 0;
|
||||
end;
|
||||
|
||||
procedure TKonsole.Paint(BottomRow: Boolean);
|
||||
var
|
||||
Buffer: array[Byte] of Char;
|
||||
Rect: TKosRect;
|
||||
J: Longint;
|
||||
Width, Height, Row: Longint;
|
||||
CaptionHeight, BorderWidth, FontWidth, FontHeight: Longint;
|
||||
begin
|
||||
CaptionHeight := 16;
|
||||
BorderWidth := 5;
|
||||
FontWidth := 6;
|
||||
FontHeight := 9;
|
||||
|
||||
kos_begindraw();
|
||||
|
||||
if not BottomRow then
|
||||
begin
|
||||
{®âà¨á®¢ª ®ª }
|
||||
kos_definewindow(60, 60, 400, 400, $63000000);
|
||||
{¢ë¢®¤ § £®«®¢ª }
|
||||
Move(FCaption[1], Buffer, Length(FCaption));
|
||||
Buffer[Length(FCaption)] := #0;
|
||||
kos_setcaption(Buffer);
|
||||
end;
|
||||
|
||||
{¯®¤£®â®¢ª ª ¢ë¢®¤ã áâப}
|
||||
Rect := GetRect();
|
||||
Dec(Rect.Width, BorderWidth * 2);
|
||||
Dec(Rect.Height, CaptionHeight + BorderWidth * 2);
|
||||
Width := Rect.Width div FontWidth;
|
||||
Height := Rect.Height - FontHeight;
|
||||
Row := FCursor.Y;
|
||||
|
||||
while Height > 0 do
|
||||
begin
|
||||
{¢ë¢®¤ ®¤®© áâப¨}
|
||||
J := Length(FLines[Row]);
|
||||
if J > Width then J := Width;
|
||||
kos_drawtext(0, Height, Copy(FLines[Row], 1, J), $00DD00, $FF000000);
|
||||
{§ «¨¢ª ®á⠢襣®áï ¯à®áâà á⢠¢ áâப¥}
|
||||
J := J * FontWidth;
|
||||
kos_drawrect(J, Height, Rect.Width - J + 1, FontHeight, $000000);
|
||||
{¯®¤£®â®¢ª ª ¢ë¢®¤ã á«¥¤ãî饩 áâப¨}
|
||||
Dec(Height, FontHeight);
|
||||
Dec(Row);
|
||||
if BottomRow or ((Row < 0) and (Length(FLines) < FMaxLines)) then Break;
|
||||
while Row < 0 do Inc(Row, FMaxLines);
|
||||
end;
|
||||
if FCursor.X <= Width then
|
||||
{®âà¨á®¢ª ªãàá®à }
|
||||
kos_drawrect((FCursor.X - 1) * FontWidth, Rect.Height - 2, FontWidth, 2, $FFFFFF);
|
||||
if not BottomRow then
|
||||
{§ «¨¢ª ®á⠢襩áï ç á⨠®ª }
|
||||
kos_drawrect(0, 0, Rect.Width + 1, Height + FontHeight, $000000);
|
||||
|
||||
kos_enddraw();
|
||||
end;
|
||||
|
||||
procedure TKonsole.Write(Message: ShortString);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
{XXX: ¢®§¬®¦ á¨âã æ¨ï ¯à¨ ª®â®à®© á®®¡é¥¨¥ ¥ ¡ã¤¥â ®â¯à ¢«¥®}
|
||||
if FOpened then
|
||||
begin
|
||||
I := 20;
|
||||
while (kos_sendmsg(FThreadID, @Message[1], Length(Message)) = 2) and (I > 0) do
|
||||
begin
|
||||
Dec(I);
|
||||
ThreadSwitch;
|
||||
end;
|
||||
end;
|
||||
end;
|
208
programs/develop/fp/rtl/kosh.inc
Normal file
208
programs/develop/fp/rtl/kosh.inc
Normal file
@ -0,0 +1,208 @@
|
||||
{}
|
||||
|
||||
type
|
||||
TKosPoint = packed record
|
||||
X: Longint;
|
||||
Y: Longint;
|
||||
end;
|
||||
|
||||
TKosRect = packed record
|
||||
case Integer of
|
||||
0: (Left, Top, Width, Height: Longint);
|
||||
1: (TopLeft, HeightWidth: TKosPoint);
|
||||
end;
|
||||
|
||||
{ User interface }
|
||||
procedure kos_definewindow(x, y, w, h: Word; style: DWord = $23FFFFFF; header: DWord = $008899FF; clframe: DWord = $008899FF);
|
||||
procedure kos_movewindow(x, y, w, h: DWord);
|
||||
function kos_getkey(): DWord;
|
||||
function kos_getevent(wait: Boolean = True): DWord;
|
||||
function kos_waitevent(timeout: DWord): DWord;
|
||||
function kos_getbutton(): DWord;
|
||||
function kos_getmousepos(): TKosPoint;
|
||||
function kos_getmousewinpos(): TKosPoint;
|
||||
function kos_getmousebuttons(): DWord;
|
||||
procedure kos_maskevents(mask: DWord);
|
||||
procedure kos_setcaption(caption: PChar);
|
||||
|
||||
{ Graphics }
|
||||
procedure kos_begindraw();
|
||||
procedure kos_enddraw();
|
||||
procedure kos_putpixel(x, y: Word; color: DWord = $000000);
|
||||
procedure kos_drawtext(x, y: Word; text: String; flags: DWord = $000000; bgcolor: DWord = $00FFFFFF);
|
||||
procedure kos_drawrect(x, y, w, h: Word; color: DWord = $000000);
|
||||
procedure kos_drawline(x1, y1, x2, y2: Word; color: DWord = $000000);
|
||||
procedure kos_drawimage(x, y, w, h, depth: DWord; image: Pointer; palette: Pointer = nil; xoffset: DWord = 0);
|
||||
procedure kos_drawimage24(x, y, w, h: DWord; image: Pointer);
|
||||
|
||||
{ Work with system }
|
||||
|
||||
{ Work with system - System services }
|
||||
function kos_killthread(tid: TThreadID): Boolean;
|
||||
procedure kos_setactivewindow(slot: TThreadSlot);
|
||||
function kos_getthreadslot(tid: TThreadID): TThreadSlot;
|
||||
|
||||
{ Work with system - Set system parameters }
|
||||
procedure kos_enablepci();
|
||||
|
||||
{ Work with system - Internal system services }
|
||||
procedure kos_switchthread();
|
||||
function kos_initheap(): DWord;
|
||||
function kos_alloc(size: DWord): Pointer;
|
||||
function kos_free(ptr: Pointer): Boolean;
|
||||
function kos_loaddriver(name: PChar): THandle;
|
||||
|
||||
{ Processes and threads }
|
||||
type
|
||||
PKosThreadInfo = ^TKosThreadInfo;
|
||||
TKosThreadInfo = packed record
|
||||
Speed: DWord;
|
||||
WindowID: Word;
|
||||
ThreadSlot: Word;
|
||||
Reserved1: Word;
|
||||
AppName: array[0..10] of Char;
|
||||
Reserved2: Byte;
|
||||
ProcessBase: Pointer;
|
||||
MemoryUsage: DWord;
|
||||
ThreadID: TThreadID;
|
||||
WindowRect: TKosRect;
|
||||
Unknown0: array[1..1066] of Byte;
|
||||
end;
|
||||
|
||||
{<EFBFBD>ãä¥à IPC}
|
||||
PKosIPC = ^TKosIPC;
|
||||
TKosIPC = packed record
|
||||
Lock: LongBool;
|
||||
Size: DWord;
|
||||
{á®®¡é¥¨¥ #1...}
|
||||
{á®®¡é¥¨¥ #2...}
|
||||
{...}
|
||||
end;
|
||||
|
||||
{‘®®¡é¥¨¥ IPC}
|
||||
PKosMessage = ^TKosMessage;
|
||||
TKosMessage = packed record
|
||||
SenderID: TThreadID;
|
||||
Size: DWord;
|
||||
{⥫® á®®¡é¥¨ï...}
|
||||
end;
|
||||
|
||||
function kos_threadinfo(info: PKosThreadInfo; slot: TThreadSlot = -1): DWord;
|
||||
function kos_newthread(entry, stack: Pointer): TThreadID;
|
||||
procedure kos_initipc(ipc: PKosIPC; size: DWord);
|
||||
function kos_sendmsg(tid: TThreadID; msg: Pointer; size: DWord): DWord;
|
||||
function kos_resizemem(size: DWord): Boolean;
|
||||
|
||||
{ File system }
|
||||
{ File system - Work with the current folder }
|
||||
|
||||
procedure kos_setdir(path: PChar);
|
||||
function kos_getdir(path: PChar; size: DWord): DWord;
|
||||
|
||||
{ File system - Work with file system with long names support }
|
||||
|
||||
const
|
||||
kfReadOnly = $01;
|
||||
kfHidden = $02;
|
||||
kfSystem = $04;
|
||||
kfLabel = $08;
|
||||
kfFolder = $10;
|
||||
kfNotArchive = $20;
|
||||
|
||||
type
|
||||
PKosFile = ^TKosFile;
|
||||
TKosFile = packed record
|
||||
SubFunc: DWord;
|
||||
Position, PositionReserved: DWord;
|
||||
Size: DWord;
|
||||
Data: Pointer;
|
||||
Name: array[0..0] of Char; {...ASCIIZ}
|
||||
end;
|
||||
|
||||
PKosBDFE = ^TKosBDFE;
|
||||
TKosBDFE = packed record
|
||||
Attributes: DWord;
|
||||
NameType: Byte; {bit0 - 0:ascii, 1:unicode}
|
||||
Reserved: array[0..2] of Byte;
|
||||
CTime: DWord; {ss,mm,hh,00}
|
||||
CDate: DWord; {dd,mm,yyyy}
|
||||
ATime: DWord;
|
||||
ADate: DWord;
|
||||
MTime: DWord;
|
||||
MDate: DWord;
|
||||
Size: QWord;
|
||||
Name: array[0..519] of Char;
|
||||
end;
|
||||
|
||||
function kos_readfile(kosfile: PKosFile; var readed: Longint): DWord;
|
||||
function kos_rewritefile(kosfile: PKosFile; var writed: Longint): DWord;
|
||||
function kos_writefile(kosfile: PKosFile; var writed: Longint): DWord;
|
||||
function kos_fileinfo(kosfile: PKosFile): DWord;
|
||||
|
||||
{ Work with hardware }
|
||||
function kos_readport(index: DWord): DWord;
|
||||
procedure kos_writeport(index, value: DWord);
|
||||
function kos_reserveport(port: DWord): Boolean;
|
||||
|
||||
{ Work with hardware - Low-level access to PCI}
|
||||
function kos_lastpcibus(): Byte;
|
||||
function kos_readpcib(bus, dev, func, reg: Byte): Byte;
|
||||
function kos_readpciw(bus, dev, func, reg: Byte): Word;
|
||||
function kos_readpcid(bus, dev, func, reg: Byte): DWord;
|
||||
|
||||
{ Other }
|
||||
procedure kos_delay(ms: DWord); {1/100 s}
|
||||
|
||||
{ my }
|
||||
type
|
||||
TKosSign = array[0..7] of Byte;
|
||||
PKosHeader = ^TKosHeader;
|
||||
TKosHeader = packed record
|
||||
sign : TKOSSign;
|
||||
version: DWord;
|
||||
start : DWord;
|
||||
size : DWord;
|
||||
memory : DWord;
|
||||
stack : DWord;
|
||||
args : PChar;
|
||||
path : PChar;
|
||||
end;
|
||||
|
||||
{var
|
||||
KonsoleIPCBuffer: array[0..4096] of Byte;}
|
||||
|
||||
type
|
||||
PKonsole = ^TKonsole;
|
||||
TKonsole = object
|
||||
private
|
||||
FCaption: String;
|
||||
FLines: array of String;
|
||||
FCursor: TKosPoint;
|
||||
FMaxLines: Word;
|
||||
FThreadID: TThreadID;
|
||||
FThreadSlot: TThreadSlot;
|
||||
FIPCBuffer: PKosIPC;
|
||||
FIPCBufferSize: DWord;
|
||||
FTerminate: Boolean;
|
||||
FOpened: Boolean;
|
||||
FKeyPressed: Word;
|
||||
function ReceiveMessage(var Message: ShortString): Boolean;
|
||||
procedure ProcessMessage(Message: ShortString);
|
||||
procedure ProcessKeyboard(Key: Word);
|
||||
function GetRect(): TKosRect;
|
||||
function GetKeyPressed(): Word;
|
||||
procedure Paint(BottomRow: Boolean = False);
|
||||
public
|
||||
constructor Init(ACaption: String = '');
|
||||
destructor Done();
|
||||
procedure Write(Message: ShortString);
|
||||
property KeyPressed: Word read GetKeyPressed;
|
||||
property Opened: Boolean read FOpened;
|
||||
property ThreadID: TThreadID read FThreadID; {JustForFun, must be hidden, do not use}
|
||||
property ThreadSlot: TThreadSlot read FThreadSlot; {JustForFun, must be hidden, do not use}
|
||||
end;
|
||||
|
||||
IStreamIO = interface
|
||||
function Read(Size: DWord = 0): AnsiString;
|
||||
procedure Write(Str: AnsiString; Error: Boolean = False);
|
||||
end;
|
35
programs/develop/fp/rtl/sysdir.inc
Normal file
35
programs/develop/fp/rtl/sysdir.inc
Normal file
@ -0,0 +1,35 @@
|
||||
{TODO}
|
||||
|
||||
procedure mkdir(const s: String); [IOCHECK];
|
||||
begin
|
||||
InOutRes := 211;
|
||||
end;
|
||||
|
||||
procedure rmdir(const s: String); [IOCHECK];
|
||||
begin
|
||||
InOutRes := 211;
|
||||
end;
|
||||
|
||||
procedure chdir(const s: String); [IOCHECK];
|
||||
var
|
||||
Path: array[Byte] of Char;
|
||||
begin
|
||||
Path := s;
|
||||
kos_setdir(Path);
|
||||
InOutRes := 0;
|
||||
end;
|
||||
|
||||
procedure getdir(DriveNr: Byte; var Dir: ShortString);
|
||||
{ DriveNr ¥ ¨á¯®«ì§ã¥âáï, ® ¢á¥£¤ ¤®«¦¥ ¡ëâì à ¢¥ 0 }
|
||||
var
|
||||
Path: array[Byte] of Char;
|
||||
Size: Longword;
|
||||
begin
|
||||
if DriveNr <> 0 then
|
||||
InOutRes := 15 { Invalid drive number (¥¯à ¢¨«ìë© ®¬¥à ãáâனá⢠) } else
|
||||
begin
|
||||
Size := kos_getdir(@Path, SizeOf(Path));
|
||||
Dir := StrPas(Path);
|
||||
InOutRes := 0;
|
||||
end;
|
||||
end;
|
145
programs/develop/fp/rtl/sysfile.inc
Normal file
145
programs/develop/fp/rtl/sysfile.inc
Normal file
@ -0,0 +1,145 @@
|
||||
{cp866}
|
||||
|
||||
function DecodeErrNo(ErrNo: DWord): Word;
|
||||
{0 = ãᯥè®
|
||||
1 = ¥ ®¯à¥¤¥«¥ ¡ § ¨/¨«¨ à §¤¥« ¦ñá⪮£® ¤¨áª (¯®¤äãªæ¨ï¬¨ 7, 8 äãªæ¨¨ 21)
|
||||
2 = äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï ¤ ®© ä ©«®¢®© á¨á⥬ë
|
||||
3 = ¥¨§¢¥áâ ï ä ©«®¢ ï á¨á⥬
|
||||
4 = § १¥à¢¨à®¢ ®, ¨ª®£¤ ¥ ¢®§¢à é ¥âáï ¢ ⥪ã饩 ॠ«¨§ 樨
|
||||
5 = ä ©« ¥ ©¤¥
|
||||
6 = ä ©« § ª®ç¨«áï
|
||||
7 = 㪠§ â¥«ì ¢¥ ¯ ¬ï⨠¯à¨«®¦¥¨ï
|
||||
8 = ¤¨áª § ¯®«¥
|
||||
9 = â ¡«¨æ FAT à §àãè¥
|
||||
10 = ¤®áâ㯠§ ¯à¥éñ
|
||||
11 = ®è¨¡ª ãáâனá⢠}
|
||||
begin
|
||||
case ErrNo of
|
||||
0: Result := 0;
|
||||
1: Result := 152;
|
||||
2: Result := 153;
|
||||
3: Result := 151;
|
||||
4: Result := 1;
|
||||
5: Result := 2;
|
||||
6: Result := 0;
|
||||
8: Result := 101;
|
||||
else
|
||||
Result := 153; { Unknown command (¥¨§¢¥áâ ï ª®¬ ¤ ) }
|
||||
end;
|
||||
end;
|
||||
|
||||
function do_isdevice(handle:thandle): Boolean;
|
||||
begin
|
||||
InOutRes := 211;
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
procedure do_close(handle: THandle);
|
||||
begin
|
||||
FreeMem(PKosFile(handle));
|
||||
InOutRes := 0;
|
||||
end;
|
||||
|
||||
procedure do_erase(p : pchar);
|
||||
begin
|
||||
InOutRes := 211;
|
||||
end;
|
||||
|
||||
procedure do_rename(p1,p2 : pchar);
|
||||
begin
|
||||
InOutRes := 211;
|
||||
end;
|
||||
|
||||
function do_write(handle: THandle; addr: Pointer; len: Longint): Longint;
|
||||
begin
|
||||
PKosFile(handle)^.Size := len;
|
||||
PKosFile(handle)^.Data := addr;
|
||||
InOutRes := DecodeErrNo(kos_writefile(PKosFile(handle), Result));
|
||||
Inc(PKosFile(handle)^.Position, Result);
|
||||
end;
|
||||
|
||||
function do_read(handle: THandle; addr: Pointer; len: Longint): Longint;
|
||||
begin
|
||||
PKosFile(handle)^.Size := len;
|
||||
PKosFile(handle)^.Data := addr;
|
||||
InOutRes := DecodeErrNo(kos_readfile(PKosFile(handle), Result));
|
||||
Inc(PKosFile(handle)^.Position, Result);
|
||||
end;
|
||||
|
||||
function do_filepos(handle: THandle): Int64;
|
||||
begin
|
||||
Result := PKosFile(handle)^.Position;
|
||||
end;
|
||||
|
||||
procedure do_seek(handle: THandle; pos: Int64);
|
||||
begin
|
||||
PKosFile(handle)^.Position := pos;
|
||||
end;
|
||||
|
||||
function do_seekend(handle: THandle): Int64;
|
||||
begin
|
||||
InOutRes := 211;
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function do_filesize(handle: THandle): Int64;
|
||||
var
|
||||
BDFE: TKosBDFE;
|
||||
begin
|
||||
PKosFile(handle)^.Data := @BDFE;
|
||||
InOutRes := DecodeErrNo(kos_fileinfo(PKosFile(handle)));
|
||||
Result := BDFE.Size;
|
||||
end;
|
||||
|
||||
procedure do_truncate(handle: THandle; pos: Int64);
|
||||
begin
|
||||
InOutRes := 211;
|
||||
end;
|
||||
|
||||
procedure do_open(var f; p: PChar; flags: Longint);
|
||||
var
|
||||
KosFile: PKosFile;
|
||||
FilePath: PChar;
|
||||
FilePathLen: Longint;
|
||||
RecSize: Longint;
|
||||
CurrDir: array[0..2048] of Char;
|
||||
CurrDirLen: Longint;
|
||||
begin
|
||||
case flags and 3 of
|
||||
0: FileRec(f).Mode := fmInput;
|
||||
1: FileRec(f).Mode := fmOutput;
|
||||
2: FileRec(f).Mode := fmInOut;
|
||||
end;
|
||||
|
||||
{”®à¬¨à®¢ ¨¥ ¨¬¥¨ ¡á®«î⮣® ¯ãâ¨}
|
||||
FilePathLen := Length(p);
|
||||
if p^ <> DirectorySeparator then
|
||||
begin
|
||||
{XXX: à §¬¥à ¡ãä¥à CurrDir ¬®¦¥â ®ª § âìáï ¥¤®áâ â®çë¬}
|
||||
CurrDirLen := kos_getdir(@CurrDir, SizeOf(CurrDir) - FilePathLen - 1) - 1;
|
||||
FilePath := @CurrDir;
|
||||
|
||||
if FilePath[CurrDirLen - 1] <> DirectorySeparator then
|
||||
begin
|
||||
FilePath[CurrDirLen] := DirectorySeparator;
|
||||
Inc(CurrDirLen);
|
||||
end;
|
||||
Move(p^, FilePath[CurrDirLen], FilePathLen + 1);
|
||||
Inc(FilePathLen, CurrDirLen);
|
||||
end else
|
||||
FilePath := p;
|
||||
|
||||
{‘®§¤ ¨¥ áâàãªâãàë TKosFile}
|
||||
RecSize := SizeOf(TKosFile) + FilePathLen;
|
||||
KosFile := GetMem(RecSize);
|
||||
FillChar(KosFile^, RecSize, 0);
|
||||
Move(FilePath^, KosFile^.Name, FilePathLen);
|
||||
FileRec(f).Handle := DWord(KosFile);
|
||||
|
||||
if flags and $1000 <> 0 then
|
||||
begin
|
||||
{ ᮧ¤ âì ä ©« }
|
||||
InOutRes := DecodeErrNo(kos_rewritefile(KosFile, RecSize));
|
||||
end else
|
||||
InOutRes := 0;
|
||||
end;
|
56
programs/develop/fp/rtl/sysheap.inc
Normal file
56
programs/develop/fp/rtl/sysheap.inc
Normal file
@ -0,0 +1,56 @@
|
||||
{TODO}
|
||||
|
||||
function SysOSAlloc(Size: PtrInt): Pointer;
|
||||
begin
|
||||
Result := kos_alloc(Size);
|
||||
end;
|
||||
|
||||
{$define HAS_SYSOSFREE}
|
||||
procedure SysOSFree(P: Pointer; Size: PtrInt);
|
||||
begin
|
||||
kos_free(P);
|
||||
end;
|
||||
|
||||
(*
|
||||
{DEBUG version}
|
||||
|
||||
var
|
||||
SysMemoryBlocks: array[Byte] of record
|
||||
Used: Boolean;
|
||||
Address: Pointer;
|
||||
Size: Longint;
|
||||
end;
|
||||
|
||||
function SysOSAlloc(Size: PtrInt): Pointer;
|
||||
var
|
||||
I: Longint;
|
||||
begin
|
||||
Result := kos_alloc(Size);
|
||||
|
||||
for I := 0 to High(SysMemoryBlocks) do
|
||||
if not SysMemoryBlocks[I].Used then
|
||||
begin
|
||||
SysMemoryBlocks[I].Used := True;
|
||||
SysMemoryBlocks[I].Address := Result;
|
||||
SysMemoryBlocks[I].Size := Size;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{$define HAS_SYSOSFREE}
|
||||
procedure SysOSFree(P: Pointer; Size: PtrInt);
|
||||
var
|
||||
B: Byte;
|
||||
I: Longint;
|
||||
begin
|
||||
B := 0;
|
||||
for I := 0 to High(SysMemoryBlocks) do
|
||||
if SysMemoryBlocks[I].Address = P then
|
||||
begin
|
||||
SysMemoryBlocks[I].Used := False;
|
||||
if SysMemoryBlocks[I].Size <> Size then B := 1 div B;
|
||||
Break;
|
||||
end;
|
||||
|
||||
kos_free(P);
|
||||
end;*)
|
52
programs/develop/fp/rtl/sysinitpas.pp
Normal file
52
programs/develop/fp/rtl/sysinitpas.pp
Normal file
@ -0,0 +1,52 @@
|
||||
{}
|
||||
|
||||
unit sysinitpas;
|
||||
|
||||
interface
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
SysInstance: Longint; external name '_FPC_SysInstance';
|
||||
|
||||
procedure PascalMain; stdcall; external name 'PASCALMAIN';
|
||||
procedure SystemExit; external name 'SystemExit';
|
||||
|
||||
procedure EntryConsole; [public, alias:'_mainCRTStartup'];
|
||||
var
|
||||
ESP_: Pointer;
|
||||
begin
|
||||
asm movl %esp, ESP_; end;
|
||||
StackTop := ESP_ + 8;
|
||||
IsConsole := True;
|
||||
PascalMain;
|
||||
SystemExit;
|
||||
end;
|
||||
|
||||
procedure EntryWindow; [public, alias:'_WinMainCRTStartup'];
|
||||
var
|
||||
ESP_: Pointer;
|
||||
begin
|
||||
asm movl %esp, ESP_; end;
|
||||
StackTop := ESP_ + 8;
|
||||
IsConsole := False;
|
||||
PascalMain;
|
||||
SystemExit;
|
||||
end;
|
||||
|
||||
procedure _FPC_DLLMainCRTStartup(_hinstance, _dllreason, _dllparam: Longint); stdcall; public name '_DLLMainCRTStartup';
|
||||
begin
|
||||
{TODO}
|
||||
IsConsole := True;
|
||||
SysInstance := _hinstance;
|
||||
end;
|
||||
|
||||
|
||||
procedure _FPC_DLLWinMainCRTStartup(_hinstance, _dllreason, _dllparam: Longint); stdcall; public name '_DLLWinMainCRTStartup';
|
||||
begin
|
||||
{TODO}
|
||||
IsConsole := False;
|
||||
SysInstance := _hinstance;
|
||||
end;
|
||||
|
||||
end.
|
11
programs/develop/fp/rtl/sysos.inc
Normal file
11
programs/develop/fp/rtl/sysos.inc
Normal file
@ -0,0 +1,11 @@
|
||||
{}
|
||||
|
||||
const
|
||||
{ flags for CreateFile }
|
||||
GENERIC_READ=$80000000;
|
||||
GENERIC_WRITE=$40000000;
|
||||
CREATE_NEW = 1;
|
||||
CREATE_ALWAYS = 2;
|
||||
OPEN_EXISTING = 3;
|
||||
OPEN_ALWAYS = 4;
|
||||
TRUNCATE_EXISTING = 5;
|
15
programs/develop/fp/rtl/sysosh.inc
Normal file
15
programs/develop/fp/rtl/sysosh.inc
Normal file
@ -0,0 +1,15 @@
|
||||
{}
|
||||
|
||||
type
|
||||
THandle = DWord;
|
||||
TThreadID = Longint;
|
||||
TThreadSlot = Longint;
|
||||
UINT = Cardinal;
|
||||
BOOL = Longbool;
|
||||
ULONG_PTR = DWord;
|
||||
SIZE_T = ULONG_PTR;
|
||||
|
||||
PRTLCriticalSection = ^TRTLCriticalSection;
|
||||
TRTLCriticalSection = packed record
|
||||
OwningThread: TThreadID;
|
||||
end;
|
201
programs/develop/fp/rtl/system.pp
Normal file
201
programs/develop/fp/rtl/system.pp
Normal file
@ -0,0 +1,201 @@
|
||||
{cp866}
|
||||
unit System;
|
||||
|
||||
{$i _defines.inc}
|
||||
{$define HAS_CMDLINE}
|
||||
|
||||
interface
|
||||
|
||||
{$i systemh.inc}
|
||||
{$i kos_def.inc}
|
||||
{$i kosh.inc}
|
||||
|
||||
const
|
||||
LineEnding = #13#10;
|
||||
LFNSupport = True;
|
||||
DirectorySeparator = '/';
|
||||
DriveSeparator = '/';
|
||||
PathSeparator = ';';
|
||||
MaxExitCode = 65535;
|
||||
MaxPathLen = 512;
|
||||
|
||||
UnusedHandle : THandle = -1;
|
||||
StdInputHandle : THandle = 0;
|
||||
StdOutputHandle: THandle = 0;
|
||||
StdErrorHandle : THandle = 0;
|
||||
FileNameCaseSensitive: Boolean = True;
|
||||
CtrlZMarksEOF: Boolean = True;
|
||||
sLineBreak = LineEnding;
|
||||
DefaultTextLineBreakStyle: TTextLineBreakStyle = tlbsCRLF;
|
||||
|
||||
var
|
||||
Argc: Longint = 0;
|
||||
Argv: PPChar = nil;
|
||||
|
||||
Konsole: TKonsole;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
SysInstance: Longint; public name '_FPC_SysInstance';
|
||||
|
||||
{$i system.inc}
|
||||
|
||||
|
||||
procedure SetupCmdLine;
|
||||
var
|
||||
Ptrs: array of PChar;
|
||||
Args: PChar;
|
||||
InQuotes: Boolean;
|
||||
I, L: Longint;
|
||||
begin
|
||||
Argc := 1;
|
||||
Args := PKosHeader(0)^.args;
|
||||
if Assigned(Args) then
|
||||
begin
|
||||
while Args^ <> #0 do
|
||||
begin
|
||||
{<7B>யãáâ¨âì «¨¤¨àãî騥 ¯à®¡¥«ë}
|
||||
while Args^ in [#1..#32] do Inc(Args);
|
||||
if Args^ = #0 then Break;
|
||||
|
||||
{‡ ¯®¬¨âì 㪠§ â¥«ì ¯ à ¬¥âà}
|
||||
SetLength(Ptrs, Argc);
|
||||
Ptrs[Argc - 1] := Args;
|
||||
Inc(Argc);
|
||||
|
||||
{<7B>யãáâ¨âì ⥪ã騩 ¯ à ¬¥âà}
|
||||
InQuotes := False;
|
||||
while (Args^ <> #0) and (not (Args^ in [#1..#32]) or InQuotes) do
|
||||
begin
|
||||
if Args^ = '"' then InQuotes := not InQuotes;
|
||||
Inc(Args);
|
||||
end;
|
||||
|
||||
{“áâ ®¢¨âì ®ª®ç ¨¥ ¯ à ¬¥âà }
|
||||
if Args^ in [#1..#32] then
|
||||
begin
|
||||
Args^ := #0;
|
||||
Inc(Args);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Argv := GetMem(Argc * SizeOf(PChar)); {XXX: ¯ ¬ïâì ¥ ®á¢®¡®¦¤ ¥âáï}
|
||||
Argv[0] := PKosHeader(0)^.path;
|
||||
for I := 1 to Argc - 1 do
|
||||
begin
|
||||
Argv[I] := Ptrs[I - 1];
|
||||
{ˆáª«îç¨âì ª ¢ë窨 ¨§ áâப¨}
|
||||
Args := Argv[I];
|
||||
L := 0;
|
||||
while Args^ <> #0 do begin Inc(Args); Inc(L); end;
|
||||
Args := Argv[I];
|
||||
while Args^ <> #0 do
|
||||
begin
|
||||
if Args^ = '"' then
|
||||
begin
|
||||
Move(PChar(Args + 1)^, Args^, L);
|
||||
Dec(L);
|
||||
end;
|
||||
Inc(Args);
|
||||
Dec(L);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ParamCount: Longint;
|
||||
begin
|
||||
Result := Argc - 1;
|
||||
end;
|
||||
|
||||
function ParamStr(L: Longint): String;
|
||||
begin
|
||||
if (L >= 0) and (L < Argc) then
|
||||
Result := StrPas(Argv[L]) else
|
||||
Result := '';
|
||||
end;
|
||||
|
||||
procedure Randomize;
|
||||
begin
|
||||
randseed := 0; {GetTickCount()}
|
||||
end;
|
||||
|
||||
const
|
||||
ProcessID: SizeUInt = 0;
|
||||
|
||||
function GetProcessID: SizeUInt;
|
||||
begin
|
||||
GetProcessID := ProcessID;
|
||||
end;
|
||||
|
||||
function CheckInitialStkLen(stklen: SizeUInt): SizeUInt;
|
||||
begin
|
||||
{TODO}
|
||||
Result := stklen;
|
||||
end;
|
||||
|
||||
{$i kos_stdio.inc}
|
||||
|
||||
procedure SysInitStdIO;
|
||||
begin
|
||||
if IsConsole then
|
||||
begin
|
||||
AssignStdin(Input);
|
||||
AssignStdout(Output);
|
||||
AssignStdout(ErrOutput);
|
||||
AssignStdout(StdOut);
|
||||
AssignStdout(StdErr);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure System_Exit; [public, alias: 'SystemExit'];
|
||||
var
|
||||
event, count: DWord;
|
||||
begin
|
||||
if IsConsole then
|
||||
begin
|
||||
if ExitCode <> 0 then
|
||||
begin
|
||||
{XXX: ®¡ï§ ⥫쮥 ãá«®¢¨¥ ®¤®¯®â®çë© Konsole}
|
||||
Write(StdErr, '[Error #', ExitCode,', press any key]');
|
||||
{®¦¨¤ âì ¦ â¨ï ª« ¢¨è¨}
|
||||
Konsole.KeyPressed;
|
||||
while Konsole.KeyPressed = 0 do kos_delay(2);
|
||||
{TODO: ¨á¯à ¢¨âì ª®áïª ¯à¨ ¯¥à¥à¨á®¢ª¥ Konsole}
|
||||
{íâ® ¥¢®§¬®¦®, â ª ª ª ªãç ®á¢®¡®¦¤ ¥âáï ¥é¥ ¤® ¢ë§®¢ í⮩ ¯à®æ¥¤ãàë}
|
||||
{¬®¦® ¯¨á âì ᢮© ¤¨á¯¥âç¥à ¯ ¬ïâ¨, ® íâ® á«®¦®}
|
||||
{ ¥á«¨ ¢ Konsole ¨á¯®«ì§®¢ âì ¢ë¤¥«¥¨¥ ¯ ¬ï⨠¯àï¬ãî ç¥à¥§ KosAPI?!}
|
||||
end;
|
||||
Close(StdErr);
|
||||
Close(StdOut);
|
||||
Close(ErrOutput);
|
||||
Close(Input);
|
||||
Close(Output);
|
||||
Konsole.Done();
|
||||
end;
|
||||
asm
|
||||
movl $-1, %eax
|
||||
int $0x40
|
||||
end;
|
||||
end;
|
||||
|
||||
{$i kos.inc}
|
||||
|
||||
begin
|
||||
SysResetFPU;
|
||||
StackLength := CheckInitialStkLen(InitialStkLen);
|
||||
StackBottom := Pointer(StackTop - StackLength);
|
||||
InitHeap;
|
||||
kos_initheap();
|
||||
SysInitExceptions;
|
||||
FPC_CpuCodeInit();
|
||||
InOutRes := 0;
|
||||
InitSystemThreads;
|
||||
Konsole.Init();
|
||||
SysInitStdIO;
|
||||
SetupCmdLine;
|
||||
InitVariantManager;
|
||||
{InitWideStringManager;}
|
||||
DispCallByIDProc := @DoDispCallByIDError;
|
||||
end.
|
386
programs/develop/fp/rtl/systhrd.inc
Normal file
386
programs/develop/fp/rtl/systhrd.inc
Normal file
@ -0,0 +1,386 @@
|
||||
{}
|
||||
|
||||
{XXX: Thread vars & TLS}
|
||||
|
||||
const
|
||||
ThreadVarBlockSize: DWord = 0;
|
||||
TLSGrowFor = 4096;
|
||||
|
||||
type
|
||||
PTLSIndex = ^TTLSIndex;
|
||||
TTLSIndex = record
|
||||
CS: TRTLCriticalSection;
|
||||
Slots: array[0..TLSGrowFor - 1] of record
|
||||
TID: DWord;
|
||||
Value: Pointer;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
TLSKey: PTLSIndex;
|
||||
|
||||
|
||||
function TLSAlloc(): PTLSIndex;
|
||||
var
|
||||
I: DWord;
|
||||
begin
|
||||
{New(Result);}
|
||||
Result := kos_alloc(SizeOf(TTLSIndex));
|
||||
InitCriticalSection(Result^.CS);
|
||||
{SetLength(Result^.Slots, TLSGrowFor);}
|
||||
for I := 0 to TLSGrowFor - 1 do
|
||||
Result^.Slots[I].TID := 0;
|
||||
end;
|
||||
|
||||
|
||||
function TLSFree(TLSIndex: PTLSIndex): Boolean;
|
||||
begin
|
||||
DoneCriticalSection(TLSIndex^.CS);
|
||||
{SetLength(TLSIndex^.Slots, 0);
|
||||
Dispose(TLSIndex);}
|
||||
kos_free(TLSIndex);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
|
||||
procedure TLSSetValue(TLSIndex: PTLSIndex; Value: Pointer);
|
||||
var
|
||||
TID, I, Count, Slot: DWord;
|
||||
begin
|
||||
TID := GetCurrentThreadID();
|
||||
EnterCriticalSection(TLSIndex^.CS);
|
||||
|
||||
Count := Length(TLSIndex^.Slots);
|
||||
Slot := Count;
|
||||
|
||||
for I := 0 to Count - 1 do
|
||||
if TLSIndex^.Slots[I].TID = TID then
|
||||
begin
|
||||
Slot := I;
|
||||
Break;
|
||||
end else
|
||||
if TLSIndex^.Slots[I].TID = 0 then
|
||||
Slot := I;
|
||||
|
||||
if Slot >= Count then
|
||||
begin
|
||||
Halt(123);
|
||||
{SetLength(TLSIndex^.Slots, Count + TLSGrowFor);
|
||||
FillChar(TLSIndex^.Slots[Count], TLSGrowFor * SizeOf(TLSIndex^.Slots[0]), #0);
|
||||
Slot := Count;}
|
||||
end;
|
||||
|
||||
TLSIndex^.Slots[Slot].TID := TID;
|
||||
TLSIndex^.Slots[Slot].Value := Value;
|
||||
|
||||
LeaveCriticalSection(TLSIndex^.CS);
|
||||
end;
|
||||
|
||||
|
||||
function TLSGetValue(TLSIndex: PTLSIndex): Pointer;
|
||||
var
|
||||
TID, I, Count: DWord;
|
||||
begin
|
||||
Result := nil;
|
||||
TID := GetCurrentThreadID();
|
||||
|
||||
EnterCriticalSection(TLSIndex^.CS);
|
||||
|
||||
Count := Length(TLSIndex^.Slots);
|
||||
|
||||
for I := 0 to Count - 1 do
|
||||
if TLSIndex^.Slots[I].TID = TID then
|
||||
begin
|
||||
Result := TLSIndex^.Slots[I].Value;
|
||||
break;
|
||||
end;
|
||||
|
||||
LeaveCriticalSection(TLSIndex^.CS);
|
||||
end;
|
||||
|
||||
|
||||
procedure SysInitThreadVar(var Offset: DWord; Size: DWord);
|
||||
begin
|
||||
Offset := ThreadVarBlockSize;
|
||||
Inc(ThreadVarBlockSize, Size);
|
||||
end;
|
||||
|
||||
procedure SysAllocateThreadVars;
|
||||
var
|
||||
DataIndex: Pointer;
|
||||
begin
|
||||
{DataIndex := GetMem(ThreadVarBlockSize);}
|
||||
DataIndex := kos_alloc(ThreadVarBlockSize);
|
||||
FillChar(DataIndex^, ThreadVarBlockSize, #0);
|
||||
TLSSetValue(TLSKey, DataIndex);
|
||||
end;
|
||||
|
||||
function SysRelocateThreadVar(Offset: DWord): Pointer;
|
||||
var
|
||||
DataIndex: Pointer;
|
||||
begin
|
||||
DataIndex := TLSGetValue(TLSKey);
|
||||
if DataIndex = nil then
|
||||
begin
|
||||
SysAllocateThreadVars;
|
||||
DataIndex := TLSGetValue(TLSKey);
|
||||
end;
|
||||
Result := DataIndex + Offset;
|
||||
end;
|
||||
|
||||
procedure SysReleaseThreadVars;
|
||||
begin
|
||||
{FreeMem(TLSGetValue(TLSKey));}
|
||||
kos_free(TLSGetValue(TLSKey));
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{XXX: Thread}
|
||||
type
|
||||
PThreadInfo = ^TThreadInfo;
|
||||
TThreadInfo = record
|
||||
Func: TThreadFunc;
|
||||
Arg: Pointer;
|
||||
StackSize: PtrUInt;
|
||||
Stack: Pointer;
|
||||
end;
|
||||
|
||||
procedure DoneThread;
|
||||
begin
|
||||
SysReleaseThreadVars;
|
||||
end;
|
||||
|
||||
procedure ThreadMain(ThreadInfo: PThreadInfo);
|
||||
var
|
||||
Result: PtrInt;
|
||||
begin
|
||||
SysAllocateThreadVars;
|
||||
with ThreadInfo^ do
|
||||
begin
|
||||
InitThread(StackSize);
|
||||
try
|
||||
Result := Func(Arg);
|
||||
except
|
||||
{TODO: Ž¡à ¡®â âì ®è¨¡ª¨}
|
||||
WriteLn(StdErr, 'Exception in thread');
|
||||
end;
|
||||
FreeMem(Stack);
|
||||
end;
|
||||
asm
|
||||
movl $-1, %eax
|
||||
int $0x40
|
||||
end;
|
||||
end;
|
||||
|
||||
function SysBeginThread(sa: Pointer; StackSize: PtrUInt; ThreadFunction: TThreadFunc; Arg: Pointer; CreationFlags: DWord; var ThreadID: TThreadID): TThreadID;
|
||||
{Stack, esp, ThreadInfo}
|
||||
|
||||
procedure EntryThreadMain; assembler;
|
||||
asm
|
||||
movl %esp, %eax
|
||||
jmp ThreadMain
|
||||
end;
|
||||
|
||||
var
|
||||
Stack: Pointer;
|
||||
ThreadInfo: PThreadInfo;
|
||||
begin
|
||||
if not IsMultiThread then
|
||||
begin
|
||||
TLSKey := TLSAlloc();
|
||||
InitThreadVars(@SysRelocateThreadVar); {XXX: must be @SysRelocateThreadvar}
|
||||
IsMultiThread := True;
|
||||
end;
|
||||
|
||||
StackSize := (StackSize + 3) div 4;
|
||||
Stack := GetMem(StackSize + SizeOf(TThreadInfo));
|
||||
ThreadInfo := PThreadInfo(PByte(Stack) + StackSize);
|
||||
ThreadInfo^.Func := ThreadFunction;
|
||||
ThreadInfo^.Arg := Arg;
|
||||
ThreadInfo^.StackSize := StackSize;
|
||||
ThreadInfo^.Stack := Stack;
|
||||
ThreadID := kos_newthread(@EntryThreadMain, ThreadInfo);
|
||||
Result := ThreadID;
|
||||
end;
|
||||
|
||||
|
||||
procedure SysEndThread(ExitCode: DWord);
|
||||
begin
|
||||
WriteLn('..SysEndThread');
|
||||
{TODO: SysEndThread}
|
||||
SysReleaseThreadVars;
|
||||
end;
|
||||
|
||||
|
||||
function SysSuspendThread(ThreadHandle: TThreadID): DWord;
|
||||
begin
|
||||
{TODO: SysSuspendThread}
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
|
||||
function SysResumeThread(ThreadHandle: TThreadID): DWord;
|
||||
begin
|
||||
{TODO: SysResumeThread}
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
|
||||
function SysKillThread(ThreadHandle: TThreadID): DWord;
|
||||
begin
|
||||
if kos_killthread(ThreadHandle) then
|
||||
Result := 0 else
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
|
||||
procedure SysThreadSwitch;
|
||||
begin
|
||||
{$ifdef EMULATOR}
|
||||
kos_delay(0);{$else}
|
||||
kos_switchthread();{$endif}
|
||||
end;
|
||||
|
||||
|
||||
function SysGetCurrentThreadID: TThreadID;
|
||||
var
|
||||
ThreadInfo: TKosThreadInfo;
|
||||
begin
|
||||
kos_threadinfo(@ThreadInfo);
|
||||
Result := ThreadInfo.ThreadID;
|
||||
end;
|
||||
|
||||
|
||||
{XXX: CriticalSection}
|
||||
procedure SysInitCriticalSection(var CS);
|
||||
begin
|
||||
PRTLCriticalSection(CS)^.OwningThread := -1;
|
||||
end;
|
||||
|
||||
procedure SysDoneCriticalSection(var CS);
|
||||
begin
|
||||
PRTLCriticalSection(CS)^.OwningThread := -1;
|
||||
end;
|
||||
|
||||
procedure SysEnterCriticalSection(var CS);
|
||||
var
|
||||
ThisThread: TThreadID;
|
||||
begin
|
||||
ThisThread := GetCurrentThreadId();
|
||||
if PRTLCriticalSection(CS)^.OwningThread <> ThisThread then
|
||||
while PRTLCriticalSection(CS)^.OwningThread <> -1 do;
|
||||
PRTLCriticalSection(CS)^.OwningThread := ThisThread;
|
||||
end;
|
||||
|
||||
procedure SysLeaveCriticalSection(var CS);
|
||||
begin
|
||||
if PRTLCriticalSection(CS)^.OwningThread = GetCurrentThreadId() then
|
||||
PRTLCriticalSection(CS)^.OwningThread := -1;
|
||||
end;
|
||||
|
||||
|
||||
{TODO: RTLEvent}
|
||||
function SysRTLEventCreate: PRTLEvent;
|
||||
begin
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
procedure SysRTLEventDestroy(State: PRTLEvent);
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{$ifndef HAS_MT_MEMORYMANAGER}
|
||||
var
|
||||
HeapMutex: TRTLCriticalSection;
|
||||
|
||||
procedure KosHeapMutexInit;
|
||||
begin
|
||||
InitCriticalSection(HeapMutex);
|
||||
end;
|
||||
|
||||
procedure KosHeapMutexDone;
|
||||
begin
|
||||
DoneCriticalSection(HeapMutex);
|
||||
end;
|
||||
|
||||
procedure KosHeapMutexLock;
|
||||
begin
|
||||
EnterCriticalSection(HeapMutex);
|
||||
end;
|
||||
|
||||
procedure KosHeapMutexUnlock;
|
||||
begin
|
||||
LeaveCriticalSection(HeapMutex);
|
||||
end;
|
||||
|
||||
const
|
||||
KosMemoryMutexManager: TMemoryMutexManager = (
|
||||
MutexInit: @KosHeapMutexInit;
|
||||
MutexDone: @KosHeapMutexDone;
|
||||
MutexLock: @KosHeapMutexLock;
|
||||
MutexUnlock: @KosHeapMutexUnlock);
|
||||
|
||||
procedure InitHeapMutexes;
|
||||
begin
|
||||
SetMemoryMutexManager(KosMemoryMutexManager);
|
||||
end;
|
||||
{$endif HAS_MT_MEMORYMANAGER}
|
||||
|
||||
|
||||
var
|
||||
KosThreadManager: TThreadManager;
|
||||
|
||||
procedure InitSystemThreads;
|
||||
begin
|
||||
ThreadID := TThreadID(1);
|
||||
with KosThreadManager do
|
||||
begin
|
||||
InitManager := nil;
|
||||
DoneManager := nil;
|
||||
|
||||
BeginThread := @SysBeginThread;
|
||||
EndThread := @SysEndThread;
|
||||
SuspendThread := @SysSuspendThread;
|
||||
ResumeThread := @SysResumeThread;
|
||||
KillThread := @SysKillThread;
|
||||
ThreadSwitch := @SysThreadSwitch;
|
||||
WaitForThreadTerminate := nil; //@NoWaitForThreadTerminate;
|
||||
ThreadSetPriority := nil; //@NoThreadSetPriority;
|
||||
ThreadGetPriority := nil; //@NoThreadGetPriority;
|
||||
|
||||
GetCurrentThreadID := @SysGetCurrentThreadID;
|
||||
InitCriticalSection := @SysInitCriticalSection;
|
||||
DoneCriticalSection := @SysDoneCriticalSection;
|
||||
EnterCriticalSection := @SysEnterCriticalSection;
|
||||
LeaveCriticalSection := @SysLeaveCriticalSection;
|
||||
InitThreadVar := @SysInitThreadVar;
|
||||
RelocateThreadVar := @SysRelocateThreadVar;
|
||||
AllocateThreadVars := @SysAllocateThreadVars;
|
||||
ReleaseThreadVars := @SysReleaseThreadVars;
|
||||
|
||||
BasicEventCreate := @NoBasicEventCreate;
|
||||
BasicEventDestroy := @NoBasicEventDestroy;
|
||||
BasicEventResetEvent := @NoBasicEventResetEvent;
|
||||
BasicEventSetEvent := @NoBasicEventSetEvent;
|
||||
BasicEventWaitFor := @NoBasicEventWaitFor;
|
||||
RTLEventCreate := @SysRTLEventCreate;
|
||||
RTLEventDestroy := @SysRTLEventDestroy;
|
||||
RTLEventSetEvent := @NoRTLEventSetEvent;
|
||||
RTLEventWaitFor := @NoRTLEventWaitFor;
|
||||
RTLEventSync := @NoRTLEventSync;
|
||||
RTLEventWaitForTimeout := @NoRTLEventWaitForTimeout;
|
||||
|
||||
SemaphoreInit := @NoSemaphoreInit;
|
||||
SemaphoreDestroy := @NoSemaphoreDestroy;
|
||||
SemaphoreWait := @NoSemaphoreWait;
|
||||
SemaphorePost := @NoSemaphorePost;
|
||||
end;
|
||||
SetThreadManager(KosThreadManager);
|
||||
{$ifndef HAS_MT_MEMORYMANAGER}
|
||||
InitHeapMutexes;
|
||||
{$endif HAS_MT_MEMORYMANAGER}
|
||||
ThreadID := GetCurrentThreadID;
|
||||
end;
|
448
programs/develop/fp/rtl/sysutils.pp
Normal file
448
programs/develop/fp/rtl/sysutils.pp
Normal file
@ -0,0 +1,448 @@
|
||||
unit sysutils;
|
||||
|
||||
{$i _defines.inc}
|
||||
|
||||
interface
|
||||
|
||||
{$mode objfpc}
|
||||
{ force ansistrings }
|
||||
{$h+}
|
||||
|
||||
{$DEFINE HAS_SLEEP}
|
||||
{-$DEFINE HAS_OSERROR}
|
||||
{-$DEFINE HAS_OSCONFIG}
|
||||
{-$DEFINE HAS_CREATEGUID}
|
||||
|
||||
|
||||
{ Include platform independent interface part }
|
||||
{$i sysutilh.inc}
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
uses
|
||||
SysConst;
|
||||
|
||||
|
||||
{-$define HASCREATEGUID}
|
||||
{-$define HASEXPANDUNCFILENAME}
|
||||
{-$DEFINE FPC_NOGENERICANSIROUTINES}
|
||||
{-$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
|
||||
{-$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
|
||||
|
||||
{ Include platform independent implementation part }
|
||||
{$i sysutils.inc}
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
File Functions
|
||||
****************************************************************************}
|
||||
|
||||
const
|
||||
FILEHANDLEPREFIX = $4000;
|
||||
type
|
||||
PFileRecord = ^TFileRecord;
|
||||
TFileRecord = record
|
||||
Filled: Boolean;
|
||||
F: File;
|
||||
end;
|
||||
var
|
||||
FileHandles: array of TFileRecord;
|
||||
|
||||
function FileRecordByHandle(Handle: THandle): PFileRecord;
|
||||
begin
|
||||
Dec(Handle, FILEHANDLEPREFIX);
|
||||
Result := @FileHandles[Handle];
|
||||
end;
|
||||
|
||||
function CreateFileRecord(): THandle;
|
||||
var
|
||||
I, C: Longword;
|
||||
begin
|
||||
Result := -1;
|
||||
C := Length(FileHandles);
|
||||
for I := 0 to C - 1 do
|
||||
if not FileHandles[I].Filled then
|
||||
begin
|
||||
Result := I;
|
||||
Break;
|
||||
end;
|
||||
if Result < 0 then
|
||||
begin
|
||||
SetLength(FileHandles, C + 1);
|
||||
Result := C;
|
||||
end;
|
||||
FileHandles[Result].Filled := True;
|
||||
FillChar(FileHandles[Result].F, SizeOf(FileRec), 0);
|
||||
Inc(Result, FILEHANDLEPREFIX);
|
||||
end;
|
||||
|
||||
procedure ReleaseFileRecord(Handle: THandle);
|
||||
begin
|
||||
FileRecordByHandle(Handle)^.Filled := False;
|
||||
end;
|
||||
|
||||
function FileOpen(const FileName: String; Mode: Integer): THandle;
|
||||
var
|
||||
F: File;
|
||||
begin
|
||||
Filemode := Mode;
|
||||
Assign(F, FileName);
|
||||
Reset(F, 1);
|
||||
if InOutRes = 0 then
|
||||
begin
|
||||
Result := CreateFileRecord();
|
||||
FileRecordByHandle(Result)^.F := F;
|
||||
end else
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function FileCreate(const FileName: String): THandle;
|
||||
var
|
||||
F: File;
|
||||
begin
|
||||
Assign(F, FileName);
|
||||
Rewrite(F, 1);
|
||||
if InOutRes = 0 then
|
||||
begin
|
||||
Result := CreateFileRecord();
|
||||
FileRecordByHandle(Result)^.F := F;
|
||||
end else
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function FileCreate(const FileName: String; Mode: Integer): THandle;
|
||||
var
|
||||
F: File;
|
||||
begin
|
||||
Filemode := Mode;
|
||||
Assign(F, FileName);
|
||||
Rewrite(F, 1);
|
||||
if InOutRes = 0 then
|
||||
begin
|
||||
Result := CreateFileRecord();
|
||||
FileRecordByHandle(Result)^.F := F;
|
||||
end else
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function FileRead(Handle: THandle; var Buffer; Count: Longint): Longint;
|
||||
begin
|
||||
BlockRead(FileRecordByHandle(Handle)^.F, Buffer, Count, Result);
|
||||
end;
|
||||
|
||||
function FileWrite(Handle: THandle; const Buffer; Count: Longint): Longint;
|
||||
begin
|
||||
BlockWrite(FileRecordByHandle(Handle)^.F, Buffer, Count, Result);
|
||||
end;
|
||||
|
||||
function FileSeek(Handle: THandle; FOffset, Origin: Longint): Longint;
|
||||
begin
|
||||
Result := FileSeek(Handle, Int64(FOffset), Origin);
|
||||
end;
|
||||
|
||||
function FileSeek(Handle: THandle; FOffset: Int64; Origin: Longint): Int64;
|
||||
var
|
||||
Position: Int64;
|
||||
begin
|
||||
case Origin of
|
||||
fsFromBeginning: Position := FOffset;
|
||||
fsFromCurrent: Position := FilePos(FileRecordByHandle(Handle)^.F) + FOffset;
|
||||
fsFromEnd: Position := FileSize(FileRecordByHandle(Handle)^.F) + FOffset;
|
||||
end;
|
||||
{TODO: ¯à®¢¥àª ᮮ⢥âá⢨ï [0..filesize]}
|
||||
Seek(FileRecordByHandle(Handle)^.F, Position);
|
||||
Result := Position;
|
||||
end;
|
||||
|
||||
procedure FileClose(Handle: THandle);
|
||||
begin
|
||||
Close(FileRecordByHandle(Handle)^.F);
|
||||
ReleaseFileRecord(Handle);
|
||||
end;
|
||||
|
||||
function FileTruncate(Handle: THandle; Size: Longint): Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function FileAge(const FileName: String): Longint;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function FileExists(const FileName: String): Boolean;
|
||||
var
|
||||
F: File;
|
||||
begin
|
||||
Assign(F, FileName);
|
||||
try
|
||||
Reset(F);
|
||||
FileSize(F);
|
||||
Result := True;
|
||||
except
|
||||
Result := False;
|
||||
end;
|
||||
Close(F);
|
||||
end;
|
||||
|
||||
function DirectoryExists(const Directory: String): Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function FindMatch(var f: TSearchRec): Longint;
|
||||
begin
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function FindFirst(const Path: String; Attr: Longint; out Rslt: TSearchRec): Longint;
|
||||
begin
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function FindNext(var Rslt: TSearchRec): Longint;
|
||||
begin
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
procedure FindClose(var F: TSearchrec);
|
||||
begin
|
||||
end;
|
||||
|
||||
function FileGetDate(Handle: THandle): Longint;
|
||||
begin
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function FileSetDate(Handle: THandle; Age: Longint): Longint;
|
||||
begin
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function FileGetAttr(const FileName: String): Longint;
|
||||
begin
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function FileSetAttr(const Filename: String; Attr: longint): Longint;
|
||||
begin
|
||||
Result := feInvalidHandle;
|
||||
end;
|
||||
|
||||
function DeleteFile(const FileName: String): Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function RenameFile(const OldName, NewName: String): Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Disk Functions
|
||||
****************************************************************************}
|
||||
|
||||
function DiskFree(drive: Byte): Int64;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function DiskSize(drive: Byte): Int64;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function GetCurrentDir: String;
|
||||
begin
|
||||
GetDir(0, Result);
|
||||
end;
|
||||
|
||||
function SetCurrentDir(const NewDir: String): Boolean;
|
||||
var
|
||||
Path: String;
|
||||
begin
|
||||
ChDir(NewDir);
|
||||
GetDir(0, Path);
|
||||
Result := Path = NewDir;
|
||||
end;
|
||||
|
||||
function CreateDir(const NewDir: String): Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function RemoveDir(const Dir: String): Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Time Functions
|
||||
****************************************************************************}
|
||||
|
||||
procedure GetLocalTime(var SystemTime: TSystemTime);
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Misc Functions
|
||||
****************************************************************************}
|
||||
|
||||
procedure Beep;
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Locale Functions
|
||||
****************************************************************************}
|
||||
|
||||
procedure GetFormatSettings;
|
||||
var
|
||||
HF: String;
|
||||
begin
|
||||
ShortMonthNames[1] := SShortMonthNameJan;
|
||||
ShortMonthNames[2] := SShortMonthNameFeb;
|
||||
ShortMonthNames[3] := SShortMonthNameMar;
|
||||
ShortMonthNames[4] := SShortMonthNameApr;
|
||||
ShortMonthNames[5] := SShortMonthNameMay;
|
||||
ShortMonthNames[6] := SShortMonthNameJun;
|
||||
ShortMonthNames[7] := SShortMonthNameJul;
|
||||
ShortMonthNames[8] := SShortMonthNameAug;
|
||||
ShortMonthNames[9] := SShortMonthNameSep;
|
||||
ShortMonthNames[10] := SShortMonthNameOct;
|
||||
ShortMonthNames[11] := SShortMonthNameNov;
|
||||
ShortMonthNames[12] := SShortMonthNameDec;
|
||||
|
||||
LongMonthNames[1] := SLongMonthNameJan;
|
||||
LongMonthNames[2] := SLongMonthNameFeb;
|
||||
LongMonthNames[3] := SLongMonthNameMar;
|
||||
LongMonthNames[4] := SLongMonthNameApr;
|
||||
LongMonthNames[5] := SLongMonthNameMay;
|
||||
LongMonthNames[6] := SLongMonthNameJun;
|
||||
LongMonthNames[7] := SLongMonthNameJul;
|
||||
LongMonthNames[8] := SLongMonthNameAug;
|
||||
LongMonthNames[9] := SLongMonthNameSep;
|
||||
LongMonthNames[10] := SLongMonthNameOct;
|
||||
LongMonthNames[11] := SLongMonthNameNov;
|
||||
LongMonthNames[12] := SLongMonthNameDec;
|
||||
|
||||
ShortDayNames[1] := SShortDayNameMon;
|
||||
ShortDayNames[2] := SShortDayNameTue;
|
||||
ShortDayNames[3] := SShortDayNameWed;
|
||||
ShortDayNames[4] := SShortDayNameThu;
|
||||
ShortDayNames[5] := SShortDayNameFri;
|
||||
ShortDayNames[6] := SShortDayNameSat;
|
||||
ShortDayNames[7] := SShortDayNameSun;
|
||||
|
||||
LongDayNames[1] := SLongDayNameMon;
|
||||
LongDayNames[2] := SLongDayNameTue;
|
||||
LongDayNames[3] := SLongDayNameWed;
|
||||
LongDayNames[4] := SLongDayNameThu;
|
||||
LongDayNames[5] := SLongDayNameFri;
|
||||
LongDayNames[6] := SLongDayNameSat;
|
||||
LongDayNames[7] := SShortDayNameSun;
|
||||
|
||||
DateSeparator := '/';
|
||||
ShortDateFormat := 'd/mm/yy';
|
||||
LongDateFormat := 'd mmmm yyyy';
|
||||
{ Time stuff }
|
||||
TimeSeparator := ':';
|
||||
TimeAMString := 'AM';
|
||||
TimePMString := 'PM';
|
||||
HF := 'hh';
|
||||
// No support for 12 hour stuff at the moment...
|
||||
ShortTimeFormat := HF + ':nn';
|
||||
LongTimeFormat := HF + ':nn:ss';
|
||||
{ Currency stuff }
|
||||
CurrencyString := '';
|
||||
CurrencyFormat := 0;
|
||||
NegCurrFormat := 0;
|
||||
{ Number stuff }
|
||||
ThousandSeparator := ',';
|
||||
DecimalSeparator := '.';
|
||||
CurrencyDecimals := 2;
|
||||
end;
|
||||
|
||||
Procedure InitInternational;
|
||||
begin
|
||||
InitInternationalGeneric;
|
||||
GetFormatSettings;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Target Dependent
|
||||
****************************************************************************}
|
||||
|
||||
function SysErrorMessage(ErrorCode: Integer): String;
|
||||
const
|
||||
MaxMsgSize = 255;
|
||||
var
|
||||
MsgBuffer: PChar;
|
||||
begin
|
||||
GetMem(MsgBuffer, MaxMsgSize);
|
||||
FillChar(MsgBuffer^, MaxMsgSize, #0);
|
||||
{TODO}
|
||||
Result := StrPas(MsgBuffer);
|
||||
FreeMem(MsgBuffer, MaxMsgSize);
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
Initialization code
|
||||
****************************************************************************}
|
||||
|
||||
Function GetEnvironmentVariable(Const EnvVar: String): String;
|
||||
begin
|
||||
Result := '';
|
||||
end;
|
||||
|
||||
Function GetEnvironmentVariableCount: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
Function GetEnvironmentString(Index : Integer) : String;
|
||||
begin
|
||||
Result := '';
|
||||
end;
|
||||
|
||||
function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString): Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function ExecuteProcess(Const Path: AnsiString; Const ComLine: Array of AnsiString): Integer;
|
||||
var
|
||||
CommandLine: AnsiString;
|
||||
i: Integer;
|
||||
begin
|
||||
Commandline:='';
|
||||
For i:=0 to high(ComLine) Do
|
||||
Commandline:=CommandLine+' '+Comline[i];
|
||||
ExecuteProcess:=ExecuteProcess(Path,CommandLine);
|
||||
end;
|
||||
|
||||
procedure Sleep(Milliseconds: Cardinal);
|
||||
begin
|
||||
kos_delay(Milliseconds div 10);
|
||||
end;
|
||||
|
||||
function GetLastOSError: Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
initialization
|
||||
InitExceptions;
|
||||
InitInternational;
|
||||
finalization
|
||||
DoneExceptions;
|
||||
end.
|
95
programs/develop/fp/rtl/tthread.inc
Normal file
95
programs/develop/fp/rtl/tthread.inc
Normal file
@ -0,0 +1,95 @@
|
||||
{ TODO }
|
||||
{ Thread management routines }
|
||||
|
||||
type
|
||||
PRaiseFrame = ^TRaiseFrame;
|
||||
TRaiseFrame = record
|
||||
NextRaise: PRaiseFrame;
|
||||
ExceptAddr: Pointer;
|
||||
ExceptObject: TObject;
|
||||
ExceptionRecord: pointer; {PExceptionRecord}
|
||||
end;
|
||||
|
||||
var
|
||||
ThreadCount: Integer;
|
||||
|
||||
|
||||
procedure AddThread;
|
||||
begin
|
||||
InterlockedIncrement(ThreadCount);
|
||||
end;
|
||||
|
||||
procedure RemoveThread;
|
||||
begin
|
||||
InterlockedDecrement(ThreadCount);
|
||||
end;
|
||||
|
||||
constructor TThread.Create(CreateSuspended: Boolean; const StackSize: SizeUInt = DefaultStackSize);
|
||||
begin
|
||||
inherited Create;
|
||||
AddThread;
|
||||
FSuspended := CreateSuspended;
|
||||
{TODO}
|
||||
FFatalException := nil;
|
||||
end;
|
||||
|
||||
destructor TThread.Destroy;
|
||||
begin
|
||||
if not FFinished and not Suspended then
|
||||
begin
|
||||
Terminate;
|
||||
WaitFor;
|
||||
end;
|
||||
FFatalException.Free;
|
||||
FFatalException := nil;
|
||||
inherited Destroy;
|
||||
RemoveThread;
|
||||
end;
|
||||
|
||||
procedure TThread.CallOnTerminate;
|
||||
begin
|
||||
FOnTerminate(Self);
|
||||
end;
|
||||
|
||||
procedure TThread.DoTerminate;
|
||||
begin
|
||||
if Assigned(FOnTerminate) then
|
||||
Synchronize(@CallOnTerminate);
|
||||
end;
|
||||
|
||||
function TThread.GetPriority: TThreadPriority;
|
||||
begin
|
||||
{TODO}
|
||||
end;
|
||||
|
||||
procedure TThread.SetPriority(Value: TThreadPriority);
|
||||
begin
|
||||
{TODO}
|
||||
end;
|
||||
|
||||
procedure TThread.SetSuspended(Value: Boolean);
|
||||
begin
|
||||
if Value <> FSuspended then
|
||||
if Value then Suspend else Resume;
|
||||
end;
|
||||
|
||||
procedure TThread.Suspend;
|
||||
begin
|
||||
FSuspended := True;
|
||||
SuspendThread(FHandle);
|
||||
end;
|
||||
|
||||
procedure TThread.Resume;
|
||||
begin
|
||||
if ResumeThread(FHandle) = 1 then FSuspended := False;
|
||||
end;
|
||||
|
||||
procedure TThread.Terminate;
|
||||
begin
|
||||
FTerminated := True;
|
||||
end;
|
||||
|
||||
function TThread.WaitFor: Integer;
|
||||
begin
|
||||
{TODO}
|
||||
end;
|
396
programs/develop/fp/rtl/types.pp
Normal file
396
programs/develop/fp/rtl/types.pp
Normal file
@ -0,0 +1,396 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit Types;
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
PLongint = System.PLongint;
|
||||
PSmallInt = System.PSmallInt;
|
||||
PDouble = System.PDouble;
|
||||
PByte = System.PByte;
|
||||
|
||||
TIntegerDynArray = array of Integer;
|
||||
TCardinalDynArray = array of Cardinal;
|
||||
TWordDynArray = array of Word;
|
||||
TSmallIntDynArray = array of SmallInt;
|
||||
TByteDynArray = array of Byte;
|
||||
TShortIntDynArray = array of ShortInt;
|
||||
TInt64DynArray = array of Int64;
|
||||
TQWordDynArray = array of QWord;
|
||||
TLongWordDynArray = array of LongWord;
|
||||
TSingleDynArray = array of Single;
|
||||
TDoubleDynArray = array of Double;
|
||||
TBooleanDynArray = array of Boolean;
|
||||
TStringDynArray = array of AnsiString;
|
||||
TWideStringDynArray = array of WideString;
|
||||
TPointerDynArray = array of Pointer;
|
||||
|
||||
TPoint =
|
||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
packed
|
||||
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
record
|
||||
X : Longint;
|
||||
Y : Longint;
|
||||
end;
|
||||
PPoint = ^TPoint;
|
||||
tagPOINT = TPoint;
|
||||
|
||||
TRect =
|
||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
packed
|
||||
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
record
|
||||
case Integer of
|
||||
0: (Left,Top,Right,Bottom : Longint);
|
||||
1: (TopLeft,BottomRight : TPoint);
|
||||
end;
|
||||
PRect = ^TRect;
|
||||
|
||||
TSize =
|
||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
packed
|
||||
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
record
|
||||
cx : Longint;
|
||||
cy : Longint;
|
||||
end;
|
||||
PSize = ^TSize;
|
||||
tagSIZE = TSize;
|
||||
// SIZE = TSize;
|
||||
|
||||
|
||||
TSmallPoint =
|
||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
packed
|
||||
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
record
|
||||
x : SmallInt;
|
||||
y : SmallInt;
|
||||
end;
|
||||
PSmallPoint = ^TSmallPoint;
|
||||
|
||||
TDuplicates = (dupIgnore, dupAccept, dupError);
|
||||
|
||||
type
|
||||
TOleChar = WideChar;
|
||||
POleStr = PWideChar;
|
||||
PPOleStr = ^POleStr;
|
||||
|
||||
TListCallback = procedure(data,arg:pointer) of object;
|
||||
TListStaticCallback = procedure(data,arg:pointer);
|
||||
|
||||
const
|
||||
GUID_NULL: TGUID = '{00000000-0000-0000-0000-000000000000}';
|
||||
|
||||
STGTY_STORAGE = 1;
|
||||
STGTY_STREAM = 2;
|
||||
STGTY_LOCKBYTES = 3;
|
||||
STGTY_PROPERTY = 4;
|
||||
|
||||
STREAM_SEEK_SET = 0;
|
||||
STREAM_SEEK_CUR = 1;
|
||||
STREAM_SEEK_END = 2;
|
||||
|
||||
LOCK_WRITE = 1;
|
||||
LOCK_EXCLUSIVE = 2;
|
||||
LOCK_ONLYONCE = 4;
|
||||
|
||||
E_FAIL = HRESULT($80004005);
|
||||
|
||||
STG_E_INVALIDFUNCTION = HRESULT($80030001);
|
||||
STG_E_FILENOTFOUND = HRESULT($80030002);
|
||||
STG_E_PATHNOTFOUND = HRESULT($80030003);
|
||||
STG_E_TOOMANYOPENFILES = HRESULT($80030004);
|
||||
STG_E_ACCESSDENIED = HRESULT($80030005);
|
||||
STG_E_INVALIDHANDLE = HRESULT($80030006);
|
||||
STG_E_INSUFFICIENTMEMORY = HRESULT($80030008);
|
||||
STG_E_INVALIDPOINTER = HRESULT($80030009);
|
||||
STG_E_NOMOREFILES = HRESULT($80030012);
|
||||
STG_E_DISKISWRITEPROTECTED = HRESULT($80030013);
|
||||
STG_E_SEEKERROR = HRESULT($80030019);
|
||||
STG_E_WRITEFAULT = HRESULT($8003001D);
|
||||
STG_E_READFAULT = HRESULT($8003001E);
|
||||
STG_E_SHAREVIOLATION = HRESULT($80030020);
|
||||
STG_E_LOCKVIOLATION = HRESULT($80030021);
|
||||
STG_E_FILEALREADYEXISTS = HRESULT($80030050);
|
||||
STG_E_INVALIDPARAMETER = HRESULT($80030057);
|
||||
STG_E_MEDIUMFULL = HRESULT($80030070);
|
||||
STG_E_PROPSETMISMATCHED = HRESULT($800300F0);
|
||||
STG_E_ABNORMALAPIEXIT = HRESULT($800300FA);
|
||||
STG_E_INVALIDHEADER = HRESULT($800300FB);
|
||||
STG_E_INVALIDNAME = HRESULT($800300FC);
|
||||
STG_E_UNKNOWN = HRESULT($800300FD);
|
||||
STG_E_UNIMPLEMENTEDFUNCTION = HRESULT($800300FE);
|
||||
STG_E_INVALIDFLAG = HRESULT($800300FF);
|
||||
STG_E_INUSE = HRESULT($80030100);
|
||||
STG_E_NOTCURRENT = HRESULT($80030101);
|
||||
STG_E_REVERTED = HRESULT($80030102);
|
||||
STG_E_CANTSAVE = HRESULT($80030103);
|
||||
STG_E_OLDFORMAT = HRESULT($80030104);
|
||||
STG_E_OLDDLL = HRESULT($80030105);
|
||||
STG_E_SHAREREQUIRED = HRESULT($80030106);
|
||||
STG_E_EXTANTMARSHALLINGS = HRESULT($80030108);
|
||||
STG_E_DOCFILECORRUPT = HRESULT($80030109);
|
||||
STG_E_BADBASEADDRESS = HRESULT($80030110);
|
||||
STG_E_INCOMPLETE = HRESULT($80030201);
|
||||
STG_E_TERMINATED = HRESULT($80030202);
|
||||
|
||||
STG_S_CONVERTED = $00030200;
|
||||
STG_S_BLOCK = $00030201;
|
||||
STG_S_RETRYNOW = $00030202;
|
||||
STG_S_MONITORING = $00030203;
|
||||
|
||||
type
|
||||
PCLSID = PGUID;
|
||||
TCLSID = TGUID;
|
||||
|
||||
LARGE_INT = Int64;
|
||||
Largeint = LARGE_INT;
|
||||
PDWord = ^DWord;
|
||||
|
||||
PDisplay = Pointer;
|
||||
PEvent = Pointer;
|
||||
|
||||
TXrmOptionDescRec = record
|
||||
end;
|
||||
XrmOptionDescRec = TXrmOptionDescRec;
|
||||
PXrmOptionDescRec = ^TXrmOptionDescRec;
|
||||
|
||||
Widget = Pointer;
|
||||
WidgetClass = Pointer;
|
||||
ArgList = Pointer;
|
||||
Region = Pointer;
|
||||
|
||||
_FILETIME =
|
||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
packed
|
||||
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
record
|
||||
dwLowDateTime : DWORD;
|
||||
dwHighDateTime : DWORD;
|
||||
end;
|
||||
TFileTime = _FILETIME;
|
||||
FILETIME = _FILETIME;
|
||||
PFileTime = ^TFileTime;
|
||||
|
||||
tagSTATSTG =
|
||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
packed
|
||||
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
record
|
||||
pwcsName : POleStr;
|
||||
dwType : Longint;
|
||||
cbSize : Largeint;
|
||||
mtime : TFileTime;
|
||||
ctime : TFileTime;
|
||||
atime : TFileTime;
|
||||
grfMode : Longint;
|
||||
grfLocksSupported : Longint;
|
||||
clsid : TCLSID;
|
||||
grfStateBits : Longint;
|
||||
reserved : Longint;
|
||||
end;
|
||||
TStatStg = tagSTATSTG;
|
||||
STATSTG = TStatStg;
|
||||
PStatStg = ^TStatStg;
|
||||
|
||||
IClassFactory = Interface(IUnknown) ['{00000001-0000-0000-C000-000000000046}']
|
||||
Function CreateInstance(Const unkOuter : IUnknown;Const riid : TGUID;Out vObject) : HResult;StdCall;
|
||||
Function LockServer(fLock : LongBool) : HResult;StdCall;
|
||||
End;
|
||||
|
||||
ISequentialStream = interface(IUnknown) ['{0c733a30-2a1c-11ce-ade5-00aa0044773d}']
|
||||
function Read(pv : Pointer;cb : DWord;pcbRead : PDWord) : HRESULT;stdcall;
|
||||
function Write(pv : Pointer;cb : DWord;pcbWritten : PDWord) : HRESULT;stdcall;
|
||||
end;
|
||||
|
||||
IStream = interface(ISequentialStream) ['{0000000C-0000-0000-C000-000000000046}']
|
||||
function Seek(dlibMove : LargeInt; dwOrigin : Longint;
|
||||
out libNewPosition : LargeInt) : HResult;stdcall;
|
||||
function SetSize(libNewSize : LargeInt) : HRESULT;stdcall;
|
||||
function CopyTo(stm: IStream;cb : LargeInt;out cbRead : LargeInt;
|
||||
out cbWritten : LargeInt) : HRESULT;stdcall;
|
||||
function Commit(grfCommitFlags : Longint) : HRESULT;stdcall;
|
||||
function Revert : HRESULT;stdcall;
|
||||
function LockRegion(libOffset : LargeInt;cb : LargeInt;
|
||||
dwLockType : Longint) : HRESULT;stdcall;
|
||||
function UnlockRegion(libOffset : LargeInt;cb : LargeInt;
|
||||
dwLockType : Longint) : HRESULT;stdcall;
|
||||
Function Stat(out statstg : TStatStg;grfStatFlag : Longint) : HRESULT;stdcall;
|
||||
function Clone(out stm : IStream) : HRESULT;stdcall;
|
||||
end;
|
||||
|
||||
function EqualRect(const r1,r2 : TRect) : Boolean;
|
||||
function Rect(Left,Top,Right,Bottom : Integer) : TRect;
|
||||
function Bounds(ALeft,ATop,AWidth,AHeight : Integer) : TRect;
|
||||
function Point(x,y : Integer) : TPoint;
|
||||
function PtInRect(const Rect : TRect; const p : TPoint) : Boolean;
|
||||
function IntersectRect(var Rect : TRect; const R1,R2 : TRect) : Boolean;
|
||||
function UnionRect(var Rect : TRect; const R1,R2 : TRect) : Boolean;
|
||||
function IsRectEmpty(const Rect : TRect) : Boolean;
|
||||
function OffsetRect(var Rect : TRect;DX : Integer;DY : Integer) : Boolean;
|
||||
function CenterPoint(const Rect: TRect): TPoint;
|
||||
function InflateRect(var Rect: TRect; dx: Integer; dy: Integer): Boolean;
|
||||
function Size(AWidth, AHeight: Integer): TSize;
|
||||
function Size(ARect: TRect): TSize;
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
function EqualRect(const r1,r2 : TRect) : Boolean;
|
||||
|
||||
begin
|
||||
EqualRect:=(r1.left=r2.left) and (r1.right=r2.right) and (r1.top=r2.top) and (r1.bottom=r2.bottom);
|
||||
end;
|
||||
|
||||
|
||||
function Rect(Left,Top,Right,Bottom : Integer) : TRect;
|
||||
|
||||
begin
|
||||
Rect.Left:=Left;
|
||||
Rect.Top:=Top;
|
||||
Rect.Right:=Right;
|
||||
Rect.Bottom:=Bottom;
|
||||
end;
|
||||
|
||||
|
||||
function Bounds(ALeft,ATop,AWidth,AHeight : Integer) : TRect;
|
||||
|
||||
begin
|
||||
Bounds.Left:=ALeft;
|
||||
Bounds.Top:=ATop;
|
||||
Bounds.Right:=ALeft+AWidth;
|
||||
Bounds.Bottom:=ATop+AHeight;
|
||||
end;
|
||||
|
||||
|
||||
function Point(x,y : Integer) : TPoint;
|
||||
|
||||
begin
|
||||
Point.x:=x;
|
||||
Point.y:=y;
|
||||
end;
|
||||
|
||||
function PtInRect(const Rect : TRect;const p : TPoint) : Boolean;
|
||||
|
||||
begin
|
||||
PtInRect:=(p.y>=Rect.Top) and
|
||||
(p.y<Rect.Bottom) and
|
||||
(p.x>=Rect.Left) and
|
||||
(p.x<Rect.Right);
|
||||
end;
|
||||
|
||||
|
||||
function IntersectRect(var Rect : TRect;const R1,R2 : TRect) : Boolean;
|
||||
|
||||
begin
|
||||
Rect:=R1;
|
||||
with R2 do
|
||||
begin
|
||||
if Left>R1.Left then
|
||||
Rect.Left:=Left;
|
||||
if Top>R1.Top then
|
||||
Rect.Top:=Top;
|
||||
if Right<R1.Right then
|
||||
Rect.Right:=Right;
|
||||
if Bottom<R1.Bottom then
|
||||
Rect.Bottom:=Bottom;
|
||||
end;
|
||||
if IsRectEmpty(Rect) then
|
||||
begin
|
||||
FillChar(Rect,SizeOf(Rect),0);
|
||||
IntersectRect:=false;
|
||||
end
|
||||
else
|
||||
IntersectRect:=true;
|
||||
end;
|
||||
|
||||
function UnionRect(var Rect : TRect;const R1,R2 : TRect) : Boolean;
|
||||
begin
|
||||
Rect:=R1;
|
||||
with R2 do
|
||||
begin
|
||||
if Left<R1.Left then
|
||||
Rect.Left:=Left;
|
||||
if Top<R1.Top then
|
||||
Rect.Top:=Top;
|
||||
if Right>R1.Right then
|
||||
Rect.Right:=Right;
|
||||
if Bottom>R1.Bottom then
|
||||
Rect.Bottom:=Bottom;
|
||||
end;
|
||||
if IsRectEmpty(Rect) then
|
||||
begin
|
||||
FillChar(Rect,SizeOf(Rect),0);
|
||||
UnionRect:=false;
|
||||
end
|
||||
else
|
||||
UnionRect:=true;
|
||||
end;
|
||||
|
||||
function IsRectEmpty(const Rect : TRect) : Boolean;
|
||||
begin
|
||||
IsRectEmpty:=(Rect.Right<=Rect.Left) or (Rect.Bottom<=Rect.Top);
|
||||
end;
|
||||
|
||||
function OffsetRect(var Rect : TRect;DX : Integer;DY : Integer) : Boolean;
|
||||
begin
|
||||
if assigned(@Rect) then
|
||||
begin
|
||||
with Rect do
|
||||
begin
|
||||
inc(Left,dx);
|
||||
inc(Top,dy);
|
||||
inc(Right,dx);
|
||||
inc(Bottom,dy);
|
||||
end;
|
||||
OffsetRect:=true;
|
||||
end
|
||||
else
|
||||
OffsetRect:=false;
|
||||
end;
|
||||
|
||||
function CenterPoint(const Rect: TRect): TPoint;
|
||||
|
||||
begin
|
||||
With Rect do
|
||||
begin
|
||||
Result.X:=(Left+Right) div 2;
|
||||
Result.Y:=(Top+Bottom) div 2;
|
||||
end;
|
||||
end;
|
||||
|
||||
function InflateRect(var Rect: TRect; dx: Integer; dy: Integer): Boolean;
|
||||
begin
|
||||
if Assigned(@Rect) then
|
||||
begin
|
||||
with Rect do
|
||||
begin
|
||||
dec(Left, dx);
|
||||
dec(Top, dy);
|
||||
inc(Right, dx);
|
||||
inc(Bottom, dy);
|
||||
end;
|
||||
Result := True;
|
||||
end
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function Size(AWidth, AHeight: Integer): TSize;
|
||||
begin
|
||||
Result.cx := AWidth;
|
||||
Result.cy := AHeight;
|
||||
end;
|
||||
|
||||
function Size(ARect: TRect): TSize;
|
||||
begin
|
||||
Result.cx := ARect.Right - ARect.Left;
|
||||
Result.cy := ARect.Bottom - ARect.Top;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end.
|
7
programs/develop/fp/rtl/windows.pp
Normal file
7
programs/develop/fp/rtl/windows.pp
Normal file
@ -0,0 +1,7 @@
|
||||
unit Windows;
|
||||
|
||||
interface
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
Loading…
Reference in New Issue
Block a user