rework project structure, base on uefi4kos
This commit is contained in:
47
kernel/boot/bootx64.asm
Normal file
47
kernel/boot/bootx64.asm
Normal file
@@ -0,0 +1,47 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2025-2025. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License. ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
format pe64 efi
|
||||
entry main
|
||||
|
||||
section '.text' code executable readable
|
||||
|
||||
include '../struct.inc'
|
||||
; include '../macros.inc'
|
||||
; include '../kglobals.inc'
|
||||
fastcall fix fstcall
|
||||
include '../proc64.inc'
|
||||
include '../const.inc'
|
||||
|
||||
purge DQ ; because of some struct DQ in const.inc
|
||||
include 'uefi64.inc'
|
||||
|
||||
proc main _efi_handle, _efi_table
|
||||
mov [efi_handle], rcx
|
||||
mov [efi_table], rdx
|
||||
mov rbx, rdx
|
||||
|
||||
mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||||
fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset], rcx, 1
|
||||
test eax, eax
|
||||
jnz $ ; what can I do here?
|
||||
mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||||
fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg_hello_k64_loader
|
||||
|
||||
jmp $
|
||||
endp
|
||||
|
||||
|
||||
section '.data' data readable writeable
|
||||
efi_handle dq 0
|
||||
efi_table dq 0
|
||||
|
||||
|
||||
section '.rodata' data readable
|
||||
msg_hello_k64_loader du "Hello from Kolibri64 efi loader",13,10,0
|
||||
|
||||
|
||||
section '.reloc' fixups data discardable
|
323
kernel/boot/uefi.inc
Normal file
323
kernel/boot/uefi.inc
Normal file
@@ -0,0 +1,323 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; Version 2, or (at your option) any later version. ;;
|
||||
;; ;;
|
||||
;; Written by Ivan Baravy ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Based on UEFI library for fasm by bzt, Public Domain. ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
EFI_LOCATE_SEARCH_TYPE:
|
||||
.AllHandles = 0
|
||||
.ByRegisterNotify = 1
|
||||
.ByProtocol = 2
|
||||
|
||||
; EFI_MEMORY_TYPE
|
||||
EFI_RESERVED_MEMORY_TYPE = 0
|
||||
EFI_LOADER_CODE = 1
|
||||
EFI_LOADER_DATA = 2
|
||||
EFI_BOOT_SERVICES_CODE = 3
|
||||
EFI_BOOT_SERVICES_DATA = 4
|
||||
EFI_RUNTIME_SERVICES_CODE = 5
|
||||
EFI_RUNTIME_SERVICES_DATA = 6
|
||||
EFI_CONVENTIONAL_MEMORY = 7
|
||||
EFI_UNUSABLE_MEMORY = 8
|
||||
EFI_ACPI_RECLAIM_MEMORY = 9
|
||||
EFI_ACPI_MEMORY_NVS = 10
|
||||
EFI_MEMORY_MAPPED_IO = 11
|
||||
EFI_MEMORY_MAPPED_IO_PORT_SPACE = 12
|
||||
EFI_PAL_CODE = 13
|
||||
EFI_PERSISTENT_MEMORY = 14
|
||||
EFI_MAX_MEMORY_TYPE = 15
|
||||
|
||||
; EFI_ALLOCATE_TYPE
|
||||
EFI_ALLOCATE_ANY_PAGES = 0
|
||||
EFI_ALLOCATE_MAX_ADDRESS = 1
|
||||
EFI_ALLOCATE_ADDRESS = 2
|
||||
|
||||
EFI_MEMORY_UC = 0x00000001
|
||||
EFI_MEMORY_WC = 0x00000002
|
||||
EFI_MEMORY_WT = 0x00000004
|
||||
EFI_MEMORY_WB = 0x00000008
|
||||
EFI_MEMORY_UCE = 0x00000010
|
||||
EFI_MEMORY_WP = 0x00001000
|
||||
EFI_MEMORY_RP = 0x00002000
|
||||
EFI_MEMORY_XP = 0x00004000
|
||||
EFI_MEMORY_NV = 0x00008000
|
||||
EFI_MEMORY_MORE_RELIABLE = 0x00010000
|
||||
EFI_MEMORY_RO = 0x00020000
|
||||
|
||||
EFI_SUCCESS = 0
|
||||
EFI_LOAD_ERROR = EFIERR or 1
|
||||
EFI_INVALID_PARAMETER = EFIERR or 2
|
||||
EFI_UNSUPPORTED = EFIERR or 3
|
||||
EFI_BAD_BUFFER_SIZE = EFIERR or 4
|
||||
EFI_BUFFER_TOO_SMALL = EFIERR or 5
|
||||
EFI_NOT_READY = EFIERR or 6
|
||||
EFI_DEVICE_ERROR = EFIERR or 7
|
||||
EFI_WRITE_PROTECTED = EFIERR or 8
|
||||
EFI_OUT_OF_RESOURCES = EFIERR or 9
|
||||
EFI_VOLUME_CORRUPTED = EFIERR or 10
|
||||
EFI_VOLUME_FULL = EFIERR or 11
|
||||
EFI_NO_MEDIA = EFIERR or 12
|
||||
EFI_MEDIA_CHANGED = EFIERR or 13
|
||||
EFI_NOT_FOUND = EFIERR or 14
|
||||
EFI_ACCESS_DENIED = EFIERR or 15
|
||||
EFI_NO_RESPONSE = EFIERR or 16
|
||||
EFI_NO_MAPPING = EFIERR or 17
|
||||
EFI_TIMEOUT = EFIERR or 18
|
||||
EFI_NOT_STARTED = EFIERR or 19
|
||||
EFI_ALREADY_STARTED = EFIERR or 20
|
||||
EFI_ABORTED = EFIERR or 21
|
||||
EFI_ICMP_ERROR = EFIERR or 22
|
||||
EFI_TFTP_ERROR = EFIERR or 23
|
||||
EFI_PROTOCOL_ERROR = EFIERR or 24
|
||||
|
||||
|
||||
EFI_FILE_SYSTEM_INFO_ID equ 0x93,0x6e,0x57,0x09,0x3f,0x6d,0xd2,0x11, \
|
||||
0x39,0x8e,0x00,0xa0,0xc9,0x69,0x72,0x3b
|
||||
|
||||
EFI_SYSTEM_TABLE_SIGNATURE equ 0x49,0x42,0x49,0x20,0x53,0x59,0x53,0x54
|
||||
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID equ 0x22,0x5b,0x4e,0x96, \
|
||||
0x59,0x64,0xd2,0x11, \
|
||||
0x8e,0x39,0x00,0xa0, \
|
||||
0xc9,0x69,0x72,0x3b
|
||||
|
||||
EFI_LOADED_IMAGE_PROTOCOL_GUID equ 0xA1,0x31,0x1b,0x5b,0x62,0x95,0xd2,0x11, \
|
||||
0x8E,0x3F,0x00,0xA0,0xC9,0x69,0x72,0x3B
|
||||
|
||||
EFI_BLOCK_IO_PROTOCOL_GUID equ 0x21,0x5b,0x4e,0x96,0x59,0x64,0xd2,0x11, \
|
||||
0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b
|
||||
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID equ 0xde,0xa9,0x42,0x90,0xdc,0x23,0x38,0x4a, \
|
||||
0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a
|
||||
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID equ 0xBB, 0x7E, 0x70, 0x2F, \
|
||||
0x1A, 0x4A, 0xd4, 0x11, \
|
||||
0x9A, 0x38, 0x00, 0x90, \
|
||||
0x27, 0x3F, 0xC1, 0x4D
|
||||
|
||||
EFI_FILE_MODE_READ = 1
|
||||
EFI_FILE_MODE_WRITE = 2
|
||||
EFI_FILE_MODE_CREATE = 0x8000000000000000
|
||||
|
||||
struct EFI_MEMORY_DESCRIPTOR
|
||||
Type dd ?
|
||||
dd ? ; align
|
||||
PhysicalStart DQ ?
|
||||
VirtualStart DQ ?
|
||||
NumberOfPages DQ ?
|
||||
Attribute DQ ?
|
||||
ends
|
||||
|
||||
struct EFI_FILE_SYSTEM_INFO
|
||||
Size DQ ?
|
||||
ReadOnly db ?
|
||||
rb 7
|
||||
VolumeSize DQ ?
|
||||
FreeSpace DQ ?
|
||||
BlockSize dd ?
|
||||
VolumeLabel rw 32
|
||||
ends
|
||||
|
||||
struct EFI_TABLE_HEADER
|
||||
Signature DQ ?
|
||||
Revision dd ?
|
||||
HeaderSize dd ?
|
||||
CRC32 dd ?
|
||||
Reserved dd ?
|
||||
ends
|
||||
|
||||
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
|
||||
Reset DN ?
|
||||
OutputString DN ?
|
||||
TestString DN ?
|
||||
QueryMode DN ?
|
||||
SetMode DN ?
|
||||
SetAttribute DN ?
|
||||
ClearScreen DN ?
|
||||
SetCursorPosition DN ?
|
||||
EnableCursor DN ?
|
||||
Mode DN ?
|
||||
ends
|
||||
|
||||
|
||||
struct SIMPLE_INPUT_INTERFACE
|
||||
Reset DN ?
|
||||
ReadKeyStroke DN ?
|
||||
WaitForKey DN ?
|
||||
ends
|
||||
|
||||
struct EFI_BOOT_SERVICES
|
||||
Hdr EFI_TABLE_HEADER
|
||||
RaisePriority DN ?
|
||||
RestorePriority DN ?
|
||||
AllocatePages DN ?
|
||||
FreePages DN ?
|
||||
GetMemoryMap DN ?
|
||||
AllocatePool DN ?
|
||||
FreePool DN ?
|
||||
CreateEvent DN ?
|
||||
SetTimer DN ?
|
||||
WaitForEvent DN ?
|
||||
SignalEvent DN ?
|
||||
CloseEvent DN ?
|
||||
CheckEvent DN ?
|
||||
InstallProtocolInterface DN ?
|
||||
ReInstallProtocolInterface DN ?
|
||||
UnInstallProtocolInterface DN ?
|
||||
HandleProtocol DN ?
|
||||
Reserved DN ?
|
||||
RegisterProtocolNotify DN ?
|
||||
LocateHandle DN ?
|
||||
LocateDevicePath DN ?
|
||||
InstallConfigurationTable DN ?
|
||||
ImageLoad DN ?
|
||||
ImageStart DN ?
|
||||
Exit DN ?
|
||||
ImageUnLoad DN ?
|
||||
ExitBootServices DN ?
|
||||
GetNextMonotonicCount DN ?
|
||||
Stall DN ?
|
||||
SetWatchdogTimer DN ?
|
||||
ConnectController DN ?
|
||||
DisConnectController DN ?
|
||||
OpenProtocol DN ?
|
||||
CloseProtocol DN ?
|
||||
OpenProtocolInformation DN ?
|
||||
ProtocolsPerHandle DN ?
|
||||
LocateHandleBuffer DN ?
|
||||
LocateProtocol DN ?
|
||||
InstallMultipleProtocolInterfaces DN ?
|
||||
UnInstallMultipleProtocolInterfaces DN ?
|
||||
CalculateCrc32 DN ?
|
||||
CopyMem DN ?
|
||||
SetMem DN ?
|
||||
ends
|
||||
|
||||
struct EFI_RUNTIME_SERVICES
|
||||
Hdr EFI_TABLE_HEADER
|
||||
GetTime DN ?
|
||||
SetTime DN ?
|
||||
GetWakeUpTime DN ?
|
||||
SetWakeUpTime DN ?
|
||||
SetVirtualAddressMap DN ?
|
||||
ConvertPointer DN ?
|
||||
GetVariable DN ?
|
||||
GetNextVariableName DN ?
|
||||
SetVariable DN ?
|
||||
GetNextHighMonoCount DN ?
|
||||
ResetSystem DN ?
|
||||
ends
|
||||
|
||||
struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
|
||||
Revision DQ ?
|
||||
OpenVolume DN ?
|
||||
ends
|
||||
|
||||
struct EFI_FILE_PROTOCOL
|
||||
Revision DQ ?
|
||||
Open DN ?
|
||||
Close DN ?
|
||||
Delete DN ?
|
||||
Read DN ?
|
||||
Write DN ?
|
||||
GetPosition DN ?
|
||||
SetPosition DN ?
|
||||
GetInfo DN ?
|
||||
SetInfo DN ?
|
||||
Flush DN ?
|
||||
OpenEx DN ?
|
||||
ReadEx DN ?
|
||||
WriteEx DN ?
|
||||
FlushEx DN ?
|
||||
ends
|
||||
|
||||
struct EFI_GRAPHICS_OUTPUT_PROTOCOL
|
||||
QueryMode DN ?
|
||||
SetMode DN ?
|
||||
Blt DN ?
|
||||
Mode DN ?
|
||||
ends
|
||||
|
||||
struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
|
||||
MaxMode dd ?
|
||||
Mode dd ?
|
||||
Info DN ?
|
||||
SizeOfInfo DN ?
|
||||
FrameBufferBase DQ ?
|
||||
FrameBufferSize DN ?
|
||||
ends
|
||||
|
||||
EFI_GRAPHICS_PIXEL_FORMAT:
|
||||
.PixelRedGreenBlueReserved8BitPerColor = 0
|
||||
.PixelBlueGreenRedReserved8BitPerColor = 1
|
||||
.PixelBitMask = 2
|
||||
.PixelBltOnly = 3
|
||||
.PixelFormatMax = 4
|
||||
|
||||
struct EFI_PIXEL_BITMASK
|
||||
RedMask dd ?
|
||||
GreenMask dd ?
|
||||
BlueMask dd ?
|
||||
ReservedMask dd ?
|
||||
ends
|
||||
|
||||
struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
|
||||
Version dd ?
|
||||
HorizontalResolution dd ?
|
||||
VerticalResolution dd ?
|
||||
PixelFormat dd ?
|
||||
PixelInformation EFI_PIXEL_BITMASK
|
||||
PixelsPerScanLine dd ?
|
||||
ends
|
||||
|
||||
struct PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
|
||||
Read DN ?
|
||||
Write DN ?
|
||||
ends
|
||||
|
||||
struct EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
|
||||
ParentHandle DN ? ; EFI_HANDLE
|
||||
PollMem DN ?
|
||||
PollIo DN ?
|
||||
Mem PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
|
||||
Io PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
|
||||
Pci PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
|
||||
CopyMem DN ?
|
||||
Map DN ?
|
||||
Unmap DN ?
|
||||
AllocateBuffer DN ?
|
||||
FreeBuffer DN ?
|
||||
Flush DN ?
|
||||
GetAttributes DN ?
|
||||
SetAttributes DN ?
|
||||
Configuration DN ?
|
||||
SegmentNumber dd ?
|
||||
ends
|
||||
|
||||
struct EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR ; described in acpi spec
|
||||
Type db ?
|
||||
Length dw ?
|
||||
ResourceType db ?
|
||||
GeneralFlags db ?
|
||||
SpecificFlags db ?
|
||||
Granularity dq ?
|
||||
RangeMinimum dq ?
|
||||
RangeMaximum dq ?
|
||||
TranslationOffset dq ?
|
||||
AddressLength dq ?
|
||||
ends
|
||||
|
||||
EFI_RESOURCE_DESCRIPTOR_TYPE.QWORD_ADDRESS_SPACE = 0x8a
|
||||
EFI_RESOURCE_DESCRIPTOR_TYPE.END_TAG = 0x79
|
||||
|
||||
EFI_RESOURCE_TYPE.MEMORY = 0
|
||||
EFI_RESOURCE_TYPE.IO = 1
|
||||
EFI_RESOURCE_TYPE.BUS = 2
|
58
kernel/boot/uefi64.inc
Normal file
58
kernel/boot/uefi64.inc
Normal file
@@ -0,0 +1,58 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; Version 2, or (at your option) any later version. ;;
|
||||
;; ;;
|
||||
;; Written by Ivan Baravy ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Based on UEFI library for fasm by bzt, Public Domain. ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
DN fix dq ; native
|
||||
|
||||
include "uefi.inc"
|
||||
|
||||
EFIERR = 0x8000000000000000
|
||||
|
||||
struct EFI_SYSTEM_TABLE
|
||||
Hdr EFI_TABLE_HEADER
|
||||
FirmwareVendor DN ?
|
||||
FirmwareRevision dd ?
|
||||
dd ?
|
||||
ConsoleInHandle DN ?
|
||||
ConIn DN ?
|
||||
ConsoleOutHandle DN ?
|
||||
ConOut DN ?
|
||||
StandardErrorHandle DN ?
|
||||
StdErr DN ?
|
||||
RuntimeServices DN ?
|
||||
BootServices DN ?
|
||||
NumberOfTableEntries DN ?
|
||||
ConfigurationTable DN ?
|
||||
ends
|
||||
|
||||
struct EFI_CONFIGURATION_TABLE
|
||||
VendorGUID rd 4
|
||||
VendorTable DN ?
|
||||
ends
|
||||
|
||||
struct EFI_LOADED_IMAGE_PROTOCOL
|
||||
Revision dd ?
|
||||
dd ?
|
||||
ParentHandle DN ?
|
||||
SystemTable DN ?
|
||||
DeviceHandle DN ?
|
||||
FilePath DN ?
|
||||
Reserved DN ?
|
||||
LoadOptionsSize dd ?
|
||||
dd ?
|
||||
ImageBase DN ?
|
||||
ImageSize dq ?
|
||||
ImageCodeType dd ?
|
||||
ImageDataType dd ?
|
||||
UnLoad DN ?
|
||||
ends
|
10
kernel/const.inc
Normal file
10
kernel/const.inc
Normal file
@@ -0,0 +1,10 @@
|
||||
struct DQ
|
||||
union
|
||||
lo dd ?
|
||||
hi_be dd ? ; big endian
|
||||
ends
|
||||
union
|
||||
hi dd ?
|
||||
lo_be dd ?
|
||||
ends
|
||||
ends
|
618
kernel/proc64.inc
Normal file
618
kernel/proc64.inc
Normal file
@@ -0,0 +1,618 @@
|
||||
|
||||
; Macroinstructions for defining and calling procedures (x64 version)
|
||||
|
||||
macro invoke proc,[arg]
|
||||
{ common fastcall [proc],arg }
|
||||
|
||||
macro fastcall proc,[arg]
|
||||
{ common local stackspace,argscount,counter
|
||||
if argscount < 4
|
||||
stackspace = 4*8
|
||||
else if argscount and 1
|
||||
stackspace = (argscount+1)*8
|
||||
else
|
||||
stackspace = argscount*8
|
||||
end if
|
||||
counter = 0
|
||||
if stackspace
|
||||
if defined current@frame
|
||||
if current@frame<stackspace
|
||||
current@frame = stackspace
|
||||
end if
|
||||
else
|
||||
if stackspace
|
||||
sub rsp, stackspace
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
forward
|
||||
counter = counter + 1
|
||||
define type@param
|
||||
define definition@param arg
|
||||
match =float value,definition@param
|
||||
\{ define definition@param value
|
||||
define type@param float \}
|
||||
match =addr value,definition@param
|
||||
\{ define definition@param value
|
||||
define type@param addr \}
|
||||
match any=,any,definition@param
|
||||
\{ \local ..string,..continue
|
||||
jmp ..continue
|
||||
align sizeof.TCHAR
|
||||
..string TCHAR definition@param,0
|
||||
..continue:
|
||||
define definition@param ..string
|
||||
define type@param addr \}
|
||||
match any,definition@param
|
||||
\{ match \`any,any
|
||||
\\{ \\local ..string,..continue
|
||||
jmp ..continue
|
||||
align sizeof.TCHAR
|
||||
..string TCHAR definition@param,0
|
||||
..continue:
|
||||
define definition@param ..string
|
||||
define type@param addr \\} \}
|
||||
match param,definition@param
|
||||
\{ local opcode,origin
|
||||
size@param = 0
|
||||
if param eqtype 0 | param eqtype 0f | type@param eq addr
|
||||
size@param = 8
|
||||
else if param eqtype byte 0 | param eqtype byte 0f
|
||||
match prefix value,definition@param
|
||||
\\{ if prefix eq qword
|
||||
size@param = 8
|
||||
else if prefix eq dword
|
||||
size@param = 4
|
||||
else if prefix eq word
|
||||
size@param = 2
|
||||
else if prefix eq byte
|
||||
size@param = 1
|
||||
end if \\}
|
||||
else if ~ param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
|
||||
virtual
|
||||
origin = $
|
||||
inc param
|
||||
load opcode byte from origin
|
||||
if opcode = 67h | opcode = 41h
|
||||
load opcode byte from origin+1
|
||||
end if
|
||||
if opcode and 0F8h = 48h
|
||||
size@param = 8
|
||||
else if opcode = 66h
|
||||
size@param = 2
|
||||
else if opcode = 0FFh
|
||||
size@param = 4
|
||||
else
|
||||
size@param = 1
|
||||
end if
|
||||
end virtual
|
||||
end if
|
||||
if counter = 1
|
||||
if type@param eq float
|
||||
if ~ param eq xmm0
|
||||
if size@param = 4
|
||||
if param eqtype byte 0 | param eqtype byte 0f
|
||||
mov eax, param
|
||||
movd xmm0, eax
|
||||
else
|
||||
movd xmm0, param
|
||||
end if
|
||||
else
|
||||
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
|
||||
mov rax, param
|
||||
movq xmm0, rax
|
||||
else
|
||||
movq xmm0, param
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
if vararg@fastcall & ~ param eq rcx
|
||||
movq rcx, xmm0
|
||||
end if
|
||||
else if type@param eq addr
|
||||
if ~ param eq rcx
|
||||
lea rcx, [param]
|
||||
end if
|
||||
else if size@param = 8
|
||||
if ~ param eq rcx
|
||||
mov rcx, param
|
||||
end if
|
||||
else if size@param = 4
|
||||
if ~ param eq ecx
|
||||
mov ecx, param
|
||||
end if
|
||||
else if size@param = 2
|
||||
if ~ param eq cx
|
||||
mov cx, param
|
||||
end if
|
||||
else if size@param = 1
|
||||
if ~ param eq cl
|
||||
mov cl, param
|
||||
end if
|
||||
end if
|
||||
else if counter = 2
|
||||
if type@param eq float
|
||||
if ~ param eq xmm1
|
||||
if size@param = 4
|
||||
if param eqtype byte 0 | param eqtype byte 0f
|
||||
mov eax, param
|
||||
movd xmm1, eax
|
||||
else
|
||||
movd xmm1, param
|
||||
end if
|
||||
else
|
||||
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
|
||||
mov rax, param
|
||||
movq xmm1, rax
|
||||
else
|
||||
movq xmm1, param
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
if vararg@fastcall & ~ param eq rdx
|
||||
movq rdx, xmm1
|
||||
end if
|
||||
else if type@param eq addr
|
||||
if ~ param eq rdx
|
||||
lea rdx, [param]
|
||||
end if
|
||||
else if size@param = 8
|
||||
if ~ param eq rdx
|
||||
mov rdx, param
|
||||
end if
|
||||
else if size@param = 4
|
||||
if ~ param eq edx
|
||||
mov edx, param
|
||||
end if
|
||||
else if size@param = 2
|
||||
if ~ param eq dx
|
||||
mov dx, param
|
||||
end if
|
||||
else if size@param = 1
|
||||
if ~ param eq dl
|
||||
mov dl, param
|
||||
end if
|
||||
end if
|
||||
else if counter = 3
|
||||
if type@param eq float
|
||||
if ~ param eq xmm2
|
||||
if size@param = 4
|
||||
if param eqtype byte 0 | param eqtype byte 0f
|
||||
mov eax, param
|
||||
movd xmm2, eax
|
||||
else
|
||||
movd xmm2, param
|
||||
end if
|
||||
else
|
||||
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
|
||||
mov rax, param
|
||||
movq xmm2, rax
|
||||
else
|
||||
movq xmm2, param
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
if vararg@fastcall & ~ param eq r8
|
||||
movq r8, xmm2
|
||||
end if
|
||||
else if type@param eq addr
|
||||
if ~ param eq r8
|
||||
lea r8, [param]
|
||||
end if
|
||||
else if size@param = 8
|
||||
if ~ param eq r8
|
||||
mov r8, param
|
||||
end if
|
||||
else if size@param = 4
|
||||
if ~ param eq r8d
|
||||
mov r8d, param
|
||||
end if
|
||||
else if size@param = 2
|
||||
if ~ param eq r8w
|
||||
mov r8w, param
|
||||
end if
|
||||
else if size@param = 1
|
||||
if ~ param eq r8b
|
||||
mov r8b, param
|
||||
end if
|
||||
end if
|
||||
else if counter = 4
|
||||
if type@param eq float
|
||||
if ~ param eq xmm3
|
||||
if size@param = 4
|
||||
if param eqtype byte 0 | param eqtype byte 0f
|
||||
mov eax, param
|
||||
movd xmm3, eax
|
||||
else
|
||||
movd xmm3, param
|
||||
end if
|
||||
else
|
||||
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
|
||||
mov rax, param
|
||||
movq xmm3, rax
|
||||
else
|
||||
movq xmm3, param
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
if vararg@fastcall & ~ param eq r9
|
||||
movq r9, xmm3
|
||||
end if
|
||||
else if type@param eq addr
|
||||
if ~ param eq r9
|
||||
lea r9, [param]
|
||||
end if
|
||||
else if size@param = 8
|
||||
if ~ param eq r9
|
||||
mov r9, param
|
||||
end if
|
||||
else if size@param = 4
|
||||
if ~ param eq r9d
|
||||
mov r9d, param
|
||||
end if
|
||||
else if size@param = 2
|
||||
if ~ param eq r9w
|
||||
mov r9w, param
|
||||
end if
|
||||
else if size@param = 1
|
||||
if ~ param eq r9b
|
||||
mov r9b, param
|
||||
end if
|
||||
end if
|
||||
else
|
||||
if type@param eq addr
|
||||
lea rax, [param]
|
||||
mov [rsp+(counter-1)*8], rax
|
||||
else if param eqtype [0] | param eqtype byte [0]
|
||||
if size@param = 8
|
||||
mov rax, param
|
||||
mov [rsp+(counter-1)*8], rax
|
||||
else if size@param = 4
|
||||
mov eax, param
|
||||
mov [rsp+(counter-1)*8], eax
|
||||
else if size@param = 2
|
||||
mov ax, param
|
||||
mov [rsp+(counter-1)*8], ax
|
||||
else
|
||||
mov al, param
|
||||
mov [rsp+(counter-1)*8], al
|
||||
end if
|
||||
else if size@param = 8
|
||||
virtual
|
||||
origin = $
|
||||
mov rax, param
|
||||
load opcode byte from origin+1
|
||||
end virtual
|
||||
if opcode = 0B8h
|
||||
mov rax, param
|
||||
mov [rsp+(counter-1)*8], rax
|
||||
else
|
||||
mov qword [rsp+(counter-1)*8], param
|
||||
end if
|
||||
else if param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
|
||||
movq [rsp+(counter-1)*8], param
|
||||
else
|
||||
mov [rsp+(counter-1)*8], param
|
||||
end if
|
||||
end if \}
|
||||
common
|
||||
argscount = counter
|
||||
call proc
|
||||
if stackspace & ~defined current@frame
|
||||
add rsp, stackspace
|
||||
end if }
|
||||
|
||||
macro proc [args]
|
||||
{ common
|
||||
match name params, args>
|
||||
\{ define@proc name,<params \} }
|
||||
|
||||
prologue@proc equ prologuedef
|
||||
|
||||
macro prologuedef procname,flag,parmbytes,localbytes,reglist
|
||||
{ local loc,fill,counter
|
||||
loc = (localbytes+15) and (not 15)
|
||||
parmbase@proc equ rbp+16
|
||||
localbase@proc equ rbp-loc
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
if loc+fill
|
||||
sub rsp, loc+fill
|
||||
end if
|
||||
counter = 0
|
||||
irps reg, reglist \{ push reg
|
||||
counter = counter+1 \}
|
||||
fill = 8*(counter and 1) }
|
||||
|
||||
epilogue@proc equ epiloguedef
|
||||
|
||||
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
|
||||
{ irps reg, reglist \{ reverse pop reg \}
|
||||
leave
|
||||
retn }
|
||||
|
||||
close@proc equ
|
||||
|
||||
macro define@proc name,statement
|
||||
{ local params,flag,regs,parmbytes,localbytes,current
|
||||
if used name
|
||||
name:
|
||||
match =stdcall args, statement \{ params equ args
|
||||
flag = 11b \}
|
||||
match =stdcall, statement \{ params equ
|
||||
flag = 11b \}
|
||||
match =c args, statement \{ params equ args
|
||||
flag = 10001b \}
|
||||
match =c, statement \{ params equ
|
||||
flag = 10001b \}
|
||||
match =params, params \{ params equ statement
|
||||
flag = 10000b \}
|
||||
match =uses reglist=,args, params \{ regs equ reglist
|
||||
params equ args \}
|
||||
match =regs =uses reglist, regs params \{ regs equ reglist
|
||||
params equ \}
|
||||
match =regs, regs \{ regs equ \}
|
||||
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
|
||||
virtual at parmbase@proc
|
||||
match =,args, params \{ defargs@proc args \}
|
||||
match =args@proc args, args@proc params \{ defargs@proc args \}
|
||||
parmbytes = $-(parmbase@proc)
|
||||
end virtual
|
||||
name # % = parmbytes/8
|
||||
all@vars equ
|
||||
current = 0
|
||||
macro locals
|
||||
\{ virtual at localbase@proc+current
|
||||
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
|
||||
struc db [val] \\{ \common deflocal@proc .,db,val \\}
|
||||
struc du [val] \\{ \common deflocal@proc .,du,val \\}
|
||||
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
|
||||
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
|
||||
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
|
||||
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
|
||||
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
|
||||
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
|
||||
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
|
||||
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
|
||||
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
|
||||
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
|
||||
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
|
||||
macro endl
|
||||
\{ purge label
|
||||
restruc db,du,dw,dp,dd,dt,dq
|
||||
restruc rb,rw,rp,rd,rt,rq
|
||||
current = $-(localbase@proc)
|
||||
end virtual \}
|
||||
macro ret operand
|
||||
\{ match any, operand \\{ retn operand \\}
|
||||
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
|
||||
macro finish@proc
|
||||
\{ localbytes = current
|
||||
match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
|
||||
end if \} }
|
||||
|
||||
macro defargs@proc [arg]
|
||||
{ common
|
||||
if ~ arg eq
|
||||
forward
|
||||
local ..arg,current@arg
|
||||
match argname:type, arg
|
||||
\{ current@arg equ argname
|
||||
label ..arg type
|
||||
argname equ ..arg
|
||||
if qqword eq type
|
||||
dq ?,?,?,?
|
||||
else if dqword eq type
|
||||
dq ?,?
|
||||
else if tbyte eq type
|
||||
dq ?,?
|
||||
else
|
||||
dq ?
|
||||
end if \}
|
||||
match =current@arg,current@arg
|
||||
\{ current@arg equ arg
|
||||
arg equ ..arg
|
||||
..arg dq ? \}
|
||||
common
|
||||
args@proc equ current@arg
|
||||
forward
|
||||
restore current@arg
|
||||
common
|
||||
end if }
|
||||
|
||||
macro deflocal@proc name,def,[val] { name def val }
|
||||
|
||||
macro deflocal@proc name,def,[val]
|
||||
{ common
|
||||
match vars, all@vars \{ all@vars equ all@vars, \}
|
||||
all@vars equ all@vars name
|
||||
forward
|
||||
local ..var,..tmp
|
||||
..var def val
|
||||
match =?, val \{ ..tmp equ \}
|
||||
match any =?, val \{ ..tmp equ \}
|
||||
match any (=?), val \{ ..tmp equ \}
|
||||
match =label, def \{ ..tmp equ \}
|
||||
match tmp : value, ..tmp : val
|
||||
\{ tmp: end virtual
|
||||
initlocal@proc ..var,def value
|
||||
virtual at tmp\}
|
||||
common
|
||||
match first rest, ..var, \{ name equ first \} }
|
||||
|
||||
struc label type { label . type }
|
||||
|
||||
macro initlocal@proc name,def
|
||||
{ virtual at name
|
||||
def
|
||||
size@initlocal = $ - name
|
||||
end virtual
|
||||
position@initlocal = 0
|
||||
while size@initlocal > position@initlocal
|
||||
virtual at name
|
||||
def
|
||||
if size@initlocal - position@initlocal < 2
|
||||
current@initlocal = 1
|
||||
load byte@initlocal byte from name+position@initlocal
|
||||
else if size@initlocal - position@initlocal < 4
|
||||
current@initlocal = 2
|
||||
load word@initlocal word from name+position@initlocal
|
||||
else if size@initlocal - position@initlocal < 8
|
||||
current@initlocal = 4
|
||||
load dword@initlocal dword from name+position@initlocal
|
||||
else
|
||||
load qword@initlocal qword from name+position@initlocal
|
||||
if ( qword@initlocal > 0 & qword@initlocal < 80000000h ) | ( qword@initlocal < 0 & qword@initlocal >= -80000000h )
|
||||
current@initlocal = 8
|
||||
else
|
||||
current@initlocal = 4
|
||||
dword@initlocal = qword@initlocal and 0FFFFFFFFh
|
||||
end if
|
||||
end if
|
||||
end virtual
|
||||
if current@initlocal = 1
|
||||
mov byte [name+position@initlocal], byte@initlocal
|
||||
else if current@initlocal = 2
|
||||
mov word [name+position@initlocal], word@initlocal
|
||||
else if current@initlocal = 4
|
||||
mov dword [name+position@initlocal], dword@initlocal
|
||||
else
|
||||
mov qword [name+position@initlocal], qword@initlocal
|
||||
end if
|
||||
position@initlocal = position@initlocal + current@initlocal
|
||||
end while }
|
||||
|
||||
macro endp
|
||||
{ purge ret,locals,endl
|
||||
finish@proc
|
||||
purge finish@proc
|
||||
restore regs@proc
|
||||
match all,args@proc \{ restore all \}
|
||||
restore args@proc
|
||||
match all,all@vars \{ restore all \} }
|
||||
|
||||
macro local [var]
|
||||
{ common
|
||||
locals
|
||||
forward done@local equ
|
||||
match varname[count]:vartype, var
|
||||
\{ match =BYTE, vartype \\{ varname rb count
|
||||
restore done@local \\}
|
||||
match =WORD, vartype \\{ varname rw count
|
||||
restore done@local \\}
|
||||
match =DWORD, vartype \\{ varname rd count
|
||||
restore done@local \\}
|
||||
match =PWORD, vartype \\{ varname rp count
|
||||
restore done@local \\}
|
||||
match =QWORD, vartype \\{ varname rq count
|
||||
restore done@local \\}
|
||||
match =TBYTE, vartype \\{ varname rt count
|
||||
restore done@local \\}
|
||||
match =DQWORD, vartype \\{ label varname dqword
|
||||
rq count*2
|
||||
restore done@local \\}
|
||||
match =QQWORD, vartype \\{ label varname qqword
|
||||
rq count*4
|
||||
restore done@local \\}
|
||||
match =XWORD, vartype \\{ label varname xword
|
||||
rq count*2
|
||||
restore done@local \\}
|
||||
match =YWORD, vartype \\{ label varname yword
|
||||
rq count*4
|
||||
restore done@local \\}
|
||||
match , done@local \\{ virtual
|
||||
varname vartype
|
||||
end virtual
|
||||
rb count*sizeof.\#vartype
|
||||
restore done@local \\} \}
|
||||
match :varname:vartype, done@local:var
|
||||
\{ match =BYTE, vartype \\{ varname db ?
|
||||
restore done@local \\}
|
||||
match =WORD, vartype \\{ varname dw ?
|
||||
restore done@local \\}
|
||||
match =DWORD, vartype \\{ varname dd ?
|
||||
restore done@local \\}
|
||||
match =PWORD, vartype \\{ varname dp ?
|
||||
restore done@local \\}
|
||||
match =QWORD, vartype \\{ varname dq ?
|
||||
restore done@local \\}
|
||||
match =TBYTE, vartype \\{ varname dt ?
|
||||
restore done@local \\}
|
||||
match =DQWORD, vartype \\{ label varname dqword
|
||||
dq ?,?
|
||||
restore done@local \\}
|
||||
match =QQWORD, vartype \\{ label varname qqword
|
||||
dq ?,?,?,?
|
||||
restore done@local \\}
|
||||
match =XWORD, vartype \\{ label varname xword
|
||||
dq ?,?
|
||||
restore done@local \\}
|
||||
match =YWORD, vartype \\{ label varname yword
|
||||
dq ?,?,?,?
|
||||
restore done@local \\}
|
||||
match , done@local \\{ varname vartype
|
||||
restore done@local \\} \}
|
||||
match ,done@local
|
||||
\{ var
|
||||
restore done@local \}
|
||||
common
|
||||
endl }
|
||||
|
||||
macro frame
|
||||
{ local size,current
|
||||
if size
|
||||
sub rsp, size
|
||||
end if
|
||||
current = 0
|
||||
current@frame equ current
|
||||
size@frame equ size }
|
||||
|
||||
macro endf
|
||||
{ size@frame = current@frame
|
||||
if size@frame
|
||||
add rsp, size@frame
|
||||
end if
|
||||
restore size@frame,current@frame }
|
||||
|
||||
macro static_rsp_prologue procname,flag,parmbytes,localbytes,reglist
|
||||
{ local counter,loc,frame,current
|
||||
counter = 0
|
||||
irps reg, reglist \{ push reg
|
||||
counter = counter+1 \}
|
||||
loc = (localbytes+7) and (not 7)
|
||||
if frame & (counter+loc shr 3+1) and 1
|
||||
loc = loc + 8
|
||||
end if
|
||||
framebytes@proc equ frame+loc
|
||||
if framebytes@proc
|
||||
sub rsp, framebytes@proc
|
||||
end if
|
||||
localbase@proc equ rsp+frame
|
||||
regsbase@proc equ rsp+frame+loc
|
||||
parmbase@proc equ rsp+frame+loc+counter*8+8
|
||||
current = 0
|
||||
current@frame equ current
|
||||
size@frame equ frame }
|
||||
|
||||
macro static_rsp_epilogue procname,flag,parmbytes,localbytes,reglist
|
||||
{ if framebytes@proc
|
||||
add rsp, framebytes@proc
|
||||
end if
|
||||
irps reg, reglist \{ reverse pop reg \}
|
||||
retn }
|
||||
|
||||
macro static_rsp_close procname,flag,parmbytes,localbytes,reglist
|
||||
{ size@frame = current@frame
|
||||
restore size@frame,current@frame }
|
||||
|
||||
stdcall fix fastcall
|
||||
|
||||
macro cinvoke proc,[arg]
|
||||
{ common ccall [proc],arg }
|
||||
|
||||
macro ccall proc,[arg]
|
||||
{ common vararg@fastcall = 1
|
||||
fastcall proc,arg
|
||||
vararg@fastcall = 0 }
|
||||
|
||||
vararg@fastcall = 0
|
246
kernel/struct.inc
Normal file
246
kernel/struct.inc
Normal file
@@ -0,0 +1,246 @@
|
||||
|
||||
; Macroinstructions for defining data structures
|
||||
|
||||
macro struct name
|
||||
{ virtual at 0
|
||||
fields@struct equ name
|
||||
match child parent, name \{ fields@struct equ child,fields@\#parent \}
|
||||
sub@struct equ
|
||||
struc db [val] \{ \common define field@struct .,db,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dw [val] \{ \common define field@struct .,dw,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc du [val] \{ \common define field@struct .,du,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dd [val] \{ \common define field@struct .,dd,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dp [val] \{ \common define field@struct .,dp,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dq [val] \{ \common define field@struct .,dq,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dt [val] \{ \common define field@struct .,dt,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rb count \{ define field@struct .,db,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rw count \{ define field@struct .,dw,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rd count \{ define field@struct .,dd,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rp count \{ define field@struct .,dp,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rq count \{ define field@struct .,dq,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rt count \{ define field@struct .,dt,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro db [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,db,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dw [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dw,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro du [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,du,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dd [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dd,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dp [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dp,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dq [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dq,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dt [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dt,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rb count \{ \local anonymous
|
||||
define field@struct anonymous,db,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rw count \{ \local anonymous
|
||||
define field@struct anonymous,dw,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rd count \{ \local anonymous
|
||||
define field@struct anonymous,dd,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rp count \{ \local anonymous
|
||||
define field@struct anonymous,dp,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rq count \{ \local anonymous
|
||||
define field@struct anonymous,dq,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rt count \{ \local anonymous
|
||||
define field@struct anonymous,dt,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro union \{ fields@struct equ fields@struct,,union,<
|
||||
sub@struct equ union \}
|
||||
macro struct \{ fields@struct equ fields@struct,,substruct,<
|
||||
sub@struct equ substruct \} }
|
||||
|
||||
macro ends
|
||||
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
|
||||
restruc rb,rw,rd,rp,rq,rt
|
||||
purge db,dw,du,dd,dp,dq,dt
|
||||
purge rb,rw,rd,rp,rq,rt
|
||||
purge union,struct
|
||||
match name tail,fields@struct, \\{ if $
|
||||
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
|
||||
err
|
||||
end if \\}
|
||||
match name=,fields,fields@struct \\{ fields@struct equ
|
||||
make@struct name,fields
|
||||
define fields@\\#name fields \\}
|
||||
end virtual \}
|
||||
match any, sub@struct \{ fields@struct equ fields@struct> \}
|
||||
restore sub@struct }
|
||||
|
||||
; @dont_give_a_doxygen
|
||||
macro make@struct name,[field,type,def]
|
||||
{ common
|
||||
local define
|
||||
define equ name
|
||||
forward
|
||||
local sub
|
||||
match , field \{ make@substruct type,name,sub def
|
||||
define equ define,.,sub, \}
|
||||
match any, field \{ define equ define,.#field,type,<def> \}
|
||||
common
|
||||
match fields, define \{ define@struct fields \} }
|
||||
|
||||
; @dont_give_a_doxygen
|
||||
macro define@struct name,[field,type,def]
|
||||
{ common
|
||||
virtual
|
||||
db `name
|
||||
load initial@struct byte from 0
|
||||
if initial@struct = '.'
|
||||
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
|
||||
err
|
||||
end if
|
||||
end virtual
|
||||
local list
|
||||
list equ
|
||||
forward
|
||||
if ~ field eq .
|
||||
name#field type def
|
||||
sizeof.#name#field = $ - name#field
|
||||
else
|
||||
label name#.#type
|
||||
rb sizeof.#type
|
||||
end if
|
||||
local value
|
||||
match any, list \{ list equ list, \}
|
||||
list equ list <value>
|
||||
common
|
||||
sizeof.#name = $
|
||||
restruc name
|
||||
match values, list \{
|
||||
struc name value \\{ \\local \\..base
|
||||
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
|
||||
match , fields@struct \\\{ label \\..base
|
||||
forward
|
||||
match , value \\\\{ field type def \\\\}
|
||||
match any, value \\\\{ field type value
|
||||
if ~ field eq .
|
||||
rb sizeof.#name#field - ($-field)
|
||||
end if \\\\}
|
||||
common label . at \\..base \\\}
|
||||
\\}
|
||||
macro name value \\{
|
||||
match any, fields@struct \\\{ \\\local anonymous
|
||||
fields@struct equ fields@struct,anonymous,name,<values> \\\}
|
||||
match , fields@struct \\\{
|
||||
forward
|
||||
match , value \\\\{ type def \\\\}
|
||||
match any, value \\\\{ \\\\local ..field
|
||||
..field = $
|
||||
type value
|
||||
if ~ field eq .
|
||||
rb sizeof.#name#field - ($-..field)
|
||||
end if \\\\}
|
||||
common \\\} \\} \} }
|
||||
|
||||
; @dont_give_a_doxygen
|
||||
macro enable@substruct
|
||||
{ macro make@substruct substruct,parent,name,[field,type,def]
|
||||
\{ \common
|
||||
\local define
|
||||
define equ parent,name
|
||||
\forward
|
||||
\local sub
|
||||
match , field \\{ match any, type \\\{ enable@substruct
|
||||
make@substruct type,parent,sub def
|
||||
purge make@substruct
|
||||
define equ define,.,sub, \\\} \\}
|
||||
match any, field \\{ define equ define,.\#field,type,<def> \\}
|
||||
\common
|
||||
match fields, define \\{ define@\#substruct fields \\} \} }
|
||||
|
||||
; @dont_give_a_doxygen
|
||||
enable@substruct
|
||||
|
||||
; @dont_give_a_doxygen
|
||||
macro define@union parent,name,[field,type,def]
|
||||
{ common
|
||||
virtual at parent#.#name
|
||||
forward
|
||||
if ~ field eq .
|
||||
virtual at parent#.#name
|
||||
parent#field type def
|
||||
sizeof.#parent#field = $ - parent#field
|
||||
end virtual
|
||||
if sizeof.#parent#field > $ - parent#.#name
|
||||
rb sizeof.#parent#field - ($ - parent#.#name)
|
||||
end if
|
||||
else
|
||||
virtual at parent#.#name
|
||||
label parent#.#type
|
||||
type def
|
||||
end virtual
|
||||
label name#.#type at parent#.#name
|
||||
if sizeof.#type > $ - parent#.#name
|
||||
rb sizeof.#type - ($ - parent#.#name)
|
||||
end if
|
||||
end if
|
||||
common
|
||||
sizeof.#name = $ - parent#.#name
|
||||
end virtual
|
||||
struc name [value] \{ \common
|
||||
label .\#name
|
||||
last@union equ
|
||||
forward
|
||||
match any, last@union \\{ virtual at .\#name
|
||||
field type def
|
||||
end virtual \\}
|
||||
match , last@union \\{ match , value \\\{ field type def \\\}
|
||||
match any, value \\\{ field type value \\\} \\}
|
||||
last@union equ field
|
||||
common rb sizeof.#name - ($ - .\#name) \}
|
||||
macro name [value] \{ \common \local ..anonymous
|
||||
..anonymous name value \} }
|
||||
|
||||
; @dont_give_a_doxygen
|
||||
macro define@substruct parent,name,[field,type,def]
|
||||
{ common
|
||||
virtual at parent#.#name
|
||||
forward
|
||||
if ~ field eq .
|
||||
parent#field type def
|
||||
sizeof.#parent#field = $ - parent#field
|
||||
else
|
||||
label parent#.#type
|
||||
rb sizeof.#type
|
||||
end if
|
||||
common
|
||||
sizeof.#name = $ - parent#.#name
|
||||
end virtual
|
||||
struc name value \{
|
||||
label .\#name
|
||||
forward
|
||||
match , value \\{ field type def \\}
|
||||
match any, value \\{ field type value
|
||||
if ~ field eq .
|
||||
rb sizeof.#parent#field - ($-field)
|
||||
end if \\}
|
||||
common \}
|
||||
macro name value \{ \local ..anonymous
|
||||
..anonymous name \} }
|
Reference in New Issue
Block a user