forked from KolibriOS/kolibrios
Can we start AP, please ?
git-svn-id: svn://kolibrios.org@2437 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
aede9dbee9
commit
1fca7a07cb
@ -36,84 +36,92 @@ APIC_timer_div equ 0x3e0
|
||||
APIC_timer_init equ 0x380
|
||||
APIC_timer_cur equ 0x390
|
||||
; IOAPIC
|
||||
IOAPIC_ID equ 0x0
|
||||
IOAPIC_VER equ 0x1
|
||||
IOAPIC_ARB equ 0x2
|
||||
IOAPIC_REDTBL equ 0x10
|
||||
IOAPIC_ID equ 0x0
|
||||
IOAPIC_VER equ 0x1
|
||||
IOAPIC_ARB equ 0x2
|
||||
IOAPIC_REDTBL equ 0x10
|
||||
|
||||
IPI_INIT equ (0x6 shl 8)
|
||||
IPI_LEVEL_ASSERT equ (0x1 shl 14)
|
||||
SHORTHAND_ALL_EXCL equ (0x3 shl 18)
|
||||
|
||||
CMD_IPI_INIT equ (IPI_INIT+SHORTHAND_ALL_EXCL)
|
||||
|
||||
|
||||
|
||||
align 4
|
||||
APIC_init:
|
||||
mov [irq_mode], IRQ_PIC
|
||||
mov [irq_mode], IRQ_PIC
|
||||
|
||||
cmp [acpi_ioapic_base], 0
|
||||
jz .no_apic
|
||||
cmp [acpi_ioapic_base], 0
|
||||
jz .no_apic
|
||||
|
||||
cmp [acpi_lapic_base], 0
|
||||
jz .no_apic
|
||||
cmp [acpi_lapic_base], 0
|
||||
jz .no_apic
|
||||
|
||||
stdcall load_file, dev_data_path
|
||||
test eax, eax
|
||||
jz .no_apic
|
||||
test eax, eax
|
||||
jz .no_apic
|
||||
|
||||
mov [acpi_dev_data], eax
|
||||
mov [acpi_dev_size], ebx
|
||||
mov [acpi_dev_data], eax
|
||||
mov [acpi_dev_size], ebx
|
||||
|
||||
call IRQ_mask_all
|
||||
call IRQ_mask_all
|
||||
|
||||
; IOAPIC init
|
||||
stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
|
||||
mov [IOAPIC_base], eax
|
||||
mov [IOAPIC_base], eax
|
||||
|
||||
mov eax, IOAPIC_VER
|
||||
call IOAPIC_read
|
||||
shr eax, 16
|
||||
inc al
|
||||
call IOAPIC_read
|
||||
shr eax, 16
|
||||
inc al
|
||||
movzx eax, al
|
||||
cmp al, IRQ_RESERVED
|
||||
jbe @f
|
||||
cmp al, IRQ_RESERVED
|
||||
jbe @f
|
||||
|
||||
mov al, IRQ_RESERVED
|
||||
mov al, IRQ_RESERVED
|
||||
@@:
|
||||
mov [IRQ_COUNT], eax
|
||||
mov [IRQ_COUNT], eax
|
||||
|
||||
; Reroute IOAPIC & mask all interrupts
|
||||
xor ecx, ecx
|
||||
mov eax, IOAPIC_REDTBL
|
||||
xor ecx, ecx
|
||||
mov eax, IOAPIC_REDTBL
|
||||
@@:
|
||||
mov ebx, eax
|
||||
call IOAPIC_read
|
||||
mov ebx, eax
|
||||
call IOAPIC_read
|
||||
mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical
|
||||
mov al, cl
|
||||
mov al, cl
|
||||
add al, 0x20; vector
|
||||
or eax, 0x10000; Mask Interrupt
|
||||
cmp ecx, 16
|
||||
jb .set
|
||||
cmp ecx, 16
|
||||
jb .set
|
||||
|
||||
or eax, 0xa000;<<< level-triggered active-low for IRQ16+
|
||||
.set:
|
||||
xchg eax, ebx
|
||||
call IOAPIC_write
|
||||
inc eax
|
||||
mov ebx, eax
|
||||
call IOAPIC_read
|
||||
xchg eax, ebx
|
||||
call IOAPIC_write
|
||||
inc eax
|
||||
mov ebx, eax
|
||||
call IOAPIC_read
|
||||
or eax, 0xff000000; Destination Field
|
||||
xchg eax, ebx
|
||||
call IOAPIC_write
|
||||
inc eax
|
||||
inc ecx
|
||||
cmp ecx, [IRQ_COUNT]
|
||||
jb @b
|
||||
xchg eax, ebx
|
||||
call IOAPIC_write
|
||||
inc eax
|
||||
inc ecx
|
||||
cmp ecx, [IRQ_COUNT]
|
||||
jb @b
|
||||
|
||||
call LAPIC_init
|
||||
call LAPIC_init
|
||||
|
||||
mov [irq_mode], IRQ_APIC
|
||||
mov [irq_mode], IRQ_APIC
|
||||
|
||||
mov al, 0x70
|
||||
out 0x22, al
|
||||
mov al, 1
|
||||
out 0x23, al
|
||||
mov al, 0x70
|
||||
out 0x22, al
|
||||
mov al, 1
|
||||
out 0x23, al
|
||||
|
||||
call pci_irq_fixup
|
||||
call pci_irq_fixup
|
||||
.no_apic:
|
||||
|
||||
ret
|
||||
@ -124,82 +132,111 @@ LAPIC_init:
|
||||
; Check MSR support
|
||||
;....
|
||||
; Get LAPIC base address
|
||||
; mov ecx, 0x1b
|
||||
; rdmsr ; it may be replaced to
|
||||
; and ax, 0xf000 ; mov eax, 0xfee00000
|
||||
;mov ecx, 0x1b
|
||||
;rdmsr ; it may be replaced to
|
||||
;and ax, 0xf000 ; mov eax, 0xfee00000
|
||||
|
||||
mov [acpi_lapic_base], 0xfee00000
|
||||
; xchg bx, bx
|
||||
|
||||
stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
|
||||
mov [LAPIC_BASE], eax
|
||||
mov esi, eax
|
||||
mov [LAPIC_BASE], eax
|
||||
mov esi, eax
|
||||
|
||||
; Program Destination Format Register for Flat mode.
|
||||
mov eax, [esi + APIC_DFR]
|
||||
or eax, 0xf0000000
|
||||
mov [esi + APIC_DFR], eax
|
||||
mov eax, [esi + APIC_DFR]
|
||||
or eax, 0xf0000000
|
||||
mov [esi + APIC_DFR], eax
|
||||
|
||||
; Program Logical Destination Register.
|
||||
mov eax, [esi + APIC_LDR]
|
||||
mov eax, [esi + APIC_LDR]
|
||||
;and eax, 0xff000000
|
||||
and eax, 0x00ffffff
|
||||
and eax, 0x00ffffff
|
||||
or eax, 0x01000000;!!!!!!!!!!!!
|
||||
mov [esi + APIC_LDR], eax
|
||||
mov [esi + APIC_LDR], eax
|
||||
|
||||
; Task Priority Register initialization.
|
||||
mov eax, [esi + APIC_TPR]
|
||||
and eax, 0xffffff00
|
||||
mov [esi + APIC_TPR], eax
|
||||
mov eax, [esi + APIC_TPR]
|
||||
and eax, 0xffffff00
|
||||
mov [esi + APIC_TPR], eax
|
||||
|
||||
; Flush the queue
|
||||
mov edx, 0
|
||||
mov edx, 0
|
||||
.nxt2:
|
||||
mov ecx, 32
|
||||
mov eax, [esi + APIC_ISR + edx]
|
||||
mov ecx, 32
|
||||
mov eax, [esi + APIC_ISR + edx]
|
||||
.nxt:
|
||||
shr eax, 1
|
||||
jnc @f
|
||||
shr eax, 1
|
||||
jnc @f
|
||||
mov dword [esi + APIC_EOI], 0; EOI
|
||||
@@:
|
||||
loop .nxt
|
||||
loop .nxt
|
||||
|
||||
add edx, 0x10
|
||||
cmp edx, 0x170
|
||||
jbe .nxt2
|
||||
add edx, 0x10
|
||||
cmp edx, 0x170
|
||||
jbe .nxt2
|
||||
|
||||
; Spurious-Interrupt Vector Register initialization.
|
||||
mov eax, [esi + APIC_SVR]
|
||||
or eax, 0x1ff
|
||||
and eax, 0xfffffdff
|
||||
mov [esi + APIC_SVR], eax
|
||||
mov eax, [esi + APIC_SVR]
|
||||
or eax, 0x1ff
|
||||
and eax, 0xfffffdff
|
||||
mov [esi + APIC_SVR], eax
|
||||
|
||||
; Initialize LVT LINT0 register. (INTR)
|
||||
mov eax, 0x00700
|
||||
mov eax, 0x00700
|
||||
; mov eax, 0x10700
|
||||
mov [esi + APIC_LVT_LINT0], eax
|
||||
mov [esi + APIC_LVT_LINT0], eax
|
||||
|
||||
; Initialize LVT LINT1 register. (NMI)
|
||||
mov eax, 0x00400
|
||||
mov [esi + APIC_LVT_LINT1], eax
|
||||
mov eax, 0x00400
|
||||
mov [esi + APIC_LVT_LINT1], eax
|
||||
|
||||
; Initialize LVT Error register.
|
||||
mov eax, [esi + APIC_LVT_err]
|
||||
mov eax, [esi + APIC_LVT_err]
|
||||
or eax, 0x10000; bit 16
|
||||
mov [esi + APIC_LVT_err], eax
|
||||
mov [esi + APIC_LVT_err], eax
|
||||
|
||||
; LAPIC timer
|
||||
; pre init
|
||||
mov dword[esi + APIC_timer_div], 1011b; 1
|
||||
mov dword[esi + APIC_timer_init], 0xffffffff; max val
|
||||
push esi
|
||||
mov esi, 640 ; wait 0.64 sec
|
||||
call delay_ms
|
||||
pop esi
|
||||
mov eax, [esi + APIC_timer_cur]; read current tick couner
|
||||
xor eax, 0xffffffff ; eax = 0xffffffff - eax
|
||||
shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec
|
||||
; mov dword[esi + APIC_timer_div], 1011b; 1
|
||||
; mov dword[esi + APIC_timer_init], 0xffffffff; max val
|
||||
; push esi
|
||||
; mov esi, 640 ; wait 0.64 sec
|
||||
; call delay_ms
|
||||
; pop esi
|
||||
; mov eax, [esi + APIC_timer_cur]; read current tick couner
|
||||
; xor eax, 0xffffffff ; eax = 0xffffffff - eax
|
||||
; shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec
|
||||
|
||||
; Start (every 0.01 sec)
|
||||
mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
|
||||
mov dword[esi + APIC_timer_init], eax
|
||||
; mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
|
||||
; mov dword[esi + APIC_timer_init], eax
|
||||
xchg bx, bx
|
||||
|
||||
; mov al, 0x0F
|
||||
; out 0x70, al
|
||||
; mov al, 0x0A
|
||||
; out 0x71, al
|
||||
|
||||
; mov [OS_BASE+0x469], word (__ap_start_16) shr 4
|
||||
; mov [OS_BASE+0x469], word 0
|
||||
|
||||
mov [esi+APIC_ICRH], dword 0
|
||||
mov [esi+APIC_ICRL], dword 0xc4500
|
||||
|
||||
mov ecx, 1000
|
||||
@@:
|
||||
loop @B
|
||||
|
||||
mov [esi+APIC_ICRH], dword 0
|
||||
mov [esi+APIC_ICRL], dword 0xC4600+((0x10000+__ap_start_16) shr 12)
|
||||
; mov [esi+APIC_ICRL], dword 0xC4612
|
||||
|
||||
; mov [esi+APIC_ICRH], dword 0
|
||||
; mov [esi+APIC_ICRL], dword CMD_IPI_INIT+IPI_LEVEL_ASSERT+16
|
||||
|
||||
|
||||
|
||||
ret
|
||||
|
||||
;===========================================================
|
||||
|
@ -161,6 +161,8 @@ include "detect/biosdisk.inc"
|
||||
|
||||
; CR0 Flags - Protected mode and Paging
|
||||
|
||||
align 16
|
||||
|
||||
mov ecx, CR0_PE
|
||||
|
||||
; Enabling 32 bit protected mode
|
||||
@ -198,6 +200,20 @@ include "detect/biosdisk.inc"
|
||||
mov cr0, eax
|
||||
jmp pword os_code:B32 ; jmp to enable 32 bit mode
|
||||
|
||||
include "boot/shutdown.inc" ; shutdown or restart
|
||||
|
||||
include "data16.inc"
|
||||
|
||||
align 4096
|
||||
__ap_start_16:
|
||||
cli
|
||||
lgdt [cs:(tmp_gdt-__ap_start_16)] ; Load GDT
|
||||
mov eax, cr0 ; protected mode
|
||||
or eax, CR0_PE
|
||||
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled
|
||||
mov cr0, eax
|
||||
jmp pword os_code:__ap_start_32 ; jmp to enable 32 bit mode
|
||||
|
||||
align 8
|
||||
tmp_gdt:
|
||||
|
||||
@ -217,11 +233,37 @@ tmp_gdt:
|
||||
dw 11011111b *256 +10010010b
|
||||
db 0x00
|
||||
|
||||
include "data16.inc"
|
||||
|
||||
use32
|
||||
org $+0x10000
|
||||
|
||||
align 16
|
||||
__ap_start_32:
|
||||
mov ax, os_stack ; Selector for os
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
bt [cpu_caps-OS_BASE], CAPS_PSE
|
||||
jnc .no_PSE
|
||||
|
||||
mov ebx, cr4
|
||||
or ebx, CR4_PSE
|
||||
mov eax, PG_LARGE+PG_SW
|
||||
mov cr4, ebx
|
||||
.no_PSE:
|
||||
mov eax, sys_pgdir-OS_BASE
|
||||
mov cr3, eax
|
||||
|
||||
mov eax, cr0
|
||||
or eax, CR0_PG+CR0_WP
|
||||
mov cr0, eax
|
||||
|
||||
lgdt [gdts]
|
||||
jmp pword os_code:ap_entry
|
||||
|
||||
align 4
|
||||
B32:
|
||||
mov ax, os_stack ; Selector for os
|
||||
@ -269,6 +311,8 @@ B32:
|
||||
|
||||
; ENABLE PAGING
|
||||
|
||||
xchg bx, bx
|
||||
|
||||
mov eax, sys_pgdir-OS_BASE
|
||||
mov cr3, eax
|
||||
|
||||
@ -283,11 +327,6 @@ align 4
|
||||
bios32_entry dd ?
|
||||
tmp_page_tabs dd ?
|
||||
|
||||
use16
|
||||
org $-0x10000
|
||||
include "boot/shutdown.inc" ; shutdown or restart
|
||||
org $+0x10000
|
||||
use32
|
||||
|
||||
__DEBUG__ fix 1
|
||||
__DEBUG_LEVEL__ fix 1
|
||||
@ -295,6 +334,31 @@ include 'init.inc'
|
||||
|
||||
org OS_BASE+$
|
||||
|
||||
ap_entry:
|
||||
bt [cpu_caps], CAPS_PGE
|
||||
jnc @F
|
||||
|
||||
mov ebx, cr4
|
||||
or ebx, CR4_PGE
|
||||
mov cr4, ebx
|
||||
@@:
|
||||
.1:
|
||||
mov ebx, LFB_BASE
|
||||
mov edx, 128
|
||||
.2:
|
||||
mov ecx, 128
|
||||
mov edi, ebx
|
||||
mov eax, [_display.width]
|
||||
lea ebx, [ebx+eax*4]
|
||||
mov eax, 0xFF808080
|
||||
rep stosd
|
||||
dec edx
|
||||
jnz .2
|
||||
jmp .1
|
||||
|
||||
hlt
|
||||
jmp ap_entry
|
||||
|
||||
align 4
|
||||
high_code:
|
||||
mov ax, os_stack
|
||||
@ -317,12 +381,12 @@ high_code:
|
||||
or ebx, CR4_PGE
|
||||
mov cr4, ebx
|
||||
@@:
|
||||
xor eax, eax
|
||||
mov dword [sys_pgdir], eax
|
||||
mov dword [sys_pgdir+4], eax
|
||||
; xor eax, eax
|
||||
; mov dword [sys_pgdir], eax
|
||||
; mov dword [sys_pgdir+4], eax
|
||||
|
||||
mov eax, cr3
|
||||
mov cr3, eax ; flush TLB
|
||||
; mov eax, cr3
|
||||
; mov cr3, eax ; flush TLB
|
||||
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_init
|
||||
@ -619,6 +683,8 @@ no_mode_0x12:
|
||||
; Try to Initialize APIC
|
||||
call APIC_init
|
||||
|
||||
call LAPIC_init
|
||||
|
||||
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
|
||||
; they are used: when partitions are scanned, hd_read relies on timer
|
||||
call unmask_timer
|
||||
|
240
kernel/branches/Kolibri-acpi/struct.inc
Normal file
240
kernel/branches/Kolibri-acpi/struct.inc
Normal file
@ -0,0 +1,240 @@
|
||||
|
||||
; 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 }
|
||||
|
||||
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 \} }
|
||||
|
||||
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 \\\} \\} \} }
|
||||
|
||||
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 \\} \} }
|
||||
|
||||
enable@substruct
|
||||
|
||||
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 \} }
|
||||
|
||||
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 \} }
|
Loading…
Reference in New Issue
Block a user