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_init equ 0x380
|
||||||
APIC_timer_cur equ 0x390
|
APIC_timer_cur equ 0x390
|
||||||
; IOAPIC
|
; IOAPIC
|
||||||
IOAPIC_ID equ 0x0
|
IOAPIC_ID equ 0x0
|
||||||
IOAPIC_VER equ 0x1
|
IOAPIC_VER equ 0x1
|
||||||
IOAPIC_ARB equ 0x2
|
IOAPIC_ARB equ 0x2
|
||||||
IOAPIC_REDTBL equ 0x10
|
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
|
align 4
|
||||||
APIC_init:
|
APIC_init:
|
||||||
mov [irq_mode], IRQ_PIC
|
mov [irq_mode], IRQ_PIC
|
||||||
|
|
||||||
cmp [acpi_ioapic_base], 0
|
cmp [acpi_ioapic_base], 0
|
||||||
jz .no_apic
|
jz .no_apic
|
||||||
|
|
||||||
cmp [acpi_lapic_base], 0
|
cmp [acpi_lapic_base], 0
|
||||||
jz .no_apic
|
jz .no_apic
|
||||||
|
|
||||||
stdcall load_file, dev_data_path
|
stdcall load_file, dev_data_path
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .no_apic
|
jz .no_apic
|
||||||
|
|
||||||
mov [acpi_dev_data], eax
|
mov [acpi_dev_data], eax
|
||||||
mov [acpi_dev_size], ebx
|
mov [acpi_dev_size], ebx
|
||||||
|
|
||||||
call IRQ_mask_all
|
call IRQ_mask_all
|
||||||
|
|
||||||
; IOAPIC init
|
; IOAPIC init
|
||||||
stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
|
stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
|
||||||
mov [IOAPIC_base], eax
|
mov [IOAPIC_base], eax
|
||||||
|
|
||||||
mov eax, IOAPIC_VER
|
mov eax, IOAPIC_VER
|
||||||
call IOAPIC_read
|
call IOAPIC_read
|
||||||
shr eax, 16
|
shr eax, 16
|
||||||
inc al
|
inc al
|
||||||
movzx eax, al
|
movzx eax, al
|
||||||
cmp al, IRQ_RESERVED
|
cmp al, IRQ_RESERVED
|
||||||
jbe @f
|
jbe @f
|
||||||
|
|
||||||
mov al, IRQ_RESERVED
|
mov al, IRQ_RESERVED
|
||||||
@@:
|
@@:
|
||||||
mov [IRQ_COUNT], eax
|
mov [IRQ_COUNT], eax
|
||||||
|
|
||||||
; Reroute IOAPIC & mask all interrupts
|
; Reroute IOAPIC & mask all interrupts
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
mov eax, IOAPIC_REDTBL
|
mov eax, IOAPIC_REDTBL
|
||||||
@@:
|
@@:
|
||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
call IOAPIC_read
|
call IOAPIC_read
|
||||||
mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical
|
mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical
|
||||||
mov al, cl
|
mov al, cl
|
||||||
add al, 0x20; vector
|
add al, 0x20; vector
|
||||||
or eax, 0x10000; Mask Interrupt
|
or eax, 0x10000; Mask Interrupt
|
||||||
cmp ecx, 16
|
cmp ecx, 16
|
||||||
jb .set
|
jb .set
|
||||||
|
|
||||||
or eax, 0xa000;<<< level-triggered active-low for IRQ16+
|
or eax, 0xa000;<<< level-triggered active-low for IRQ16+
|
||||||
.set:
|
.set:
|
||||||
xchg eax, ebx
|
xchg eax, ebx
|
||||||
call IOAPIC_write
|
call IOAPIC_write
|
||||||
inc eax
|
inc eax
|
||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
call IOAPIC_read
|
call IOAPIC_read
|
||||||
or eax, 0xff000000; Destination Field
|
or eax, 0xff000000; Destination Field
|
||||||
xchg eax, ebx
|
xchg eax, ebx
|
||||||
call IOAPIC_write
|
call IOAPIC_write
|
||||||
inc eax
|
inc eax
|
||||||
inc ecx
|
inc ecx
|
||||||
cmp ecx, [IRQ_COUNT]
|
cmp ecx, [IRQ_COUNT]
|
||||||
jb @b
|
jb @b
|
||||||
|
|
||||||
call LAPIC_init
|
call LAPIC_init
|
||||||
|
|
||||||
mov [irq_mode], IRQ_APIC
|
mov [irq_mode], IRQ_APIC
|
||||||
|
|
||||||
mov al, 0x70
|
mov al, 0x70
|
||||||
out 0x22, al
|
out 0x22, al
|
||||||
mov al, 1
|
mov al, 1
|
||||||
out 0x23, al
|
out 0x23, al
|
||||||
|
|
||||||
call pci_irq_fixup
|
call pci_irq_fixup
|
||||||
.no_apic:
|
.no_apic:
|
||||||
|
|
||||||
ret
|
ret
|
||||||
@ -124,82 +132,111 @@ LAPIC_init:
|
|||||||
; Check MSR support
|
; Check MSR support
|
||||||
;....
|
;....
|
||||||
; Get LAPIC base address
|
; Get LAPIC base address
|
||||||
; mov ecx, 0x1b
|
;mov ecx, 0x1b
|
||||||
; rdmsr ; it may be replaced to
|
;rdmsr ; it may be replaced to
|
||||||
; and ax, 0xf000 ; mov eax, 0xfee00000
|
;and ax, 0xf000 ; mov eax, 0xfee00000
|
||||||
|
|
||||||
|
mov [acpi_lapic_base], 0xfee00000
|
||||||
|
; xchg bx, bx
|
||||||
|
|
||||||
stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
|
stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
|
||||||
mov [LAPIC_BASE], eax
|
mov [LAPIC_BASE], eax
|
||||||
mov esi, eax
|
mov esi, eax
|
||||||
|
|
||||||
; Program Destination Format Register for Flat mode.
|
; Program Destination Format Register for Flat mode.
|
||||||
mov eax, [esi + APIC_DFR]
|
mov eax, [esi + APIC_DFR]
|
||||||
or eax, 0xf0000000
|
or eax, 0xf0000000
|
||||||
mov [esi + APIC_DFR], eax
|
mov [esi + APIC_DFR], eax
|
||||||
|
|
||||||
; Program Logical Destination Register.
|
; Program Logical Destination Register.
|
||||||
mov eax, [esi + APIC_LDR]
|
mov eax, [esi + APIC_LDR]
|
||||||
;and eax, 0xff000000
|
;and eax, 0xff000000
|
||||||
and eax, 0x00ffffff
|
and eax, 0x00ffffff
|
||||||
or eax, 0x01000000;!!!!!!!!!!!!
|
or eax, 0x01000000;!!!!!!!!!!!!
|
||||||
mov [esi + APIC_LDR], eax
|
mov [esi + APIC_LDR], eax
|
||||||
|
|
||||||
; Task Priority Register initialization.
|
; Task Priority Register initialization.
|
||||||
mov eax, [esi + APIC_TPR]
|
mov eax, [esi + APIC_TPR]
|
||||||
and eax, 0xffffff00
|
and eax, 0xffffff00
|
||||||
mov [esi + APIC_TPR], eax
|
mov [esi + APIC_TPR], eax
|
||||||
|
|
||||||
; Flush the queue
|
; Flush the queue
|
||||||
mov edx, 0
|
mov edx, 0
|
||||||
.nxt2:
|
.nxt2:
|
||||||
mov ecx, 32
|
mov ecx, 32
|
||||||
mov eax, [esi + APIC_ISR + edx]
|
mov eax, [esi + APIC_ISR + edx]
|
||||||
.nxt:
|
.nxt:
|
||||||
shr eax, 1
|
shr eax, 1
|
||||||
jnc @f
|
jnc @f
|
||||||
mov dword [esi + APIC_EOI], 0; EOI
|
mov dword [esi + APIC_EOI], 0; EOI
|
||||||
@@:
|
@@:
|
||||||
loop .nxt
|
loop .nxt
|
||||||
|
|
||||||
add edx, 0x10
|
add edx, 0x10
|
||||||
cmp edx, 0x170
|
cmp edx, 0x170
|
||||||
jbe .nxt2
|
jbe .nxt2
|
||||||
|
|
||||||
; Spurious-Interrupt Vector Register initialization.
|
; Spurious-Interrupt Vector Register initialization.
|
||||||
mov eax, [esi + APIC_SVR]
|
mov eax, [esi + APIC_SVR]
|
||||||
or eax, 0x1ff
|
or eax, 0x1ff
|
||||||
and eax, 0xfffffdff
|
and eax, 0xfffffdff
|
||||||
mov [esi + APIC_SVR], eax
|
mov [esi + APIC_SVR], eax
|
||||||
|
|
||||||
; Initialize LVT LINT0 register. (INTR)
|
; Initialize LVT LINT0 register. (INTR)
|
||||||
mov eax, 0x00700
|
mov eax, 0x00700
|
||||||
; mov eax, 0x10700
|
; mov eax, 0x10700
|
||||||
mov [esi + APIC_LVT_LINT0], eax
|
mov [esi + APIC_LVT_LINT0], eax
|
||||||
|
|
||||||
; Initialize LVT LINT1 register. (NMI)
|
; Initialize LVT LINT1 register. (NMI)
|
||||||
mov eax, 0x00400
|
mov eax, 0x00400
|
||||||
mov [esi + APIC_LVT_LINT1], eax
|
mov [esi + APIC_LVT_LINT1], eax
|
||||||
|
|
||||||
; Initialize LVT Error register.
|
; Initialize LVT Error register.
|
||||||
mov eax, [esi + APIC_LVT_err]
|
mov eax, [esi + APIC_LVT_err]
|
||||||
or eax, 0x10000; bit 16
|
or eax, 0x10000; bit 16
|
||||||
mov [esi + APIC_LVT_err], eax
|
mov [esi + APIC_LVT_err], eax
|
||||||
|
|
||||||
; LAPIC timer
|
; LAPIC timer
|
||||||
; pre init
|
; pre init
|
||||||
mov dword[esi + APIC_timer_div], 1011b; 1
|
; mov dword[esi + APIC_timer_div], 1011b; 1
|
||||||
mov dword[esi + APIC_timer_init], 0xffffffff; max val
|
; mov dword[esi + APIC_timer_init], 0xffffffff; max val
|
||||||
push esi
|
; push esi
|
||||||
mov esi, 640 ; wait 0.64 sec
|
; mov esi, 640 ; wait 0.64 sec
|
||||||
call delay_ms
|
; call delay_ms
|
||||||
pop esi
|
; pop esi
|
||||||
mov eax, [esi + APIC_timer_cur]; read current tick couner
|
; mov eax, [esi + APIC_timer_cur]; read current tick couner
|
||||||
xor eax, 0xffffffff ; eax = 0xffffffff - eax
|
; xor eax, 0xffffffff ; eax = 0xffffffff - eax
|
||||||
shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec
|
; shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec
|
||||||
|
|
||||||
; Start (every 0.01 sec)
|
; Start (every 0.01 sec)
|
||||||
mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
|
; mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
|
||||||
mov dword[esi + APIC_timer_init], eax
|
; 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
|
ret
|
||||||
|
|
||||||
;===========================================================
|
;===========================================================
|
||||||
|
@ -161,6 +161,8 @@ include "detect/biosdisk.inc"
|
|||||||
|
|
||||||
; CR0 Flags - Protected mode and Paging
|
; CR0 Flags - Protected mode and Paging
|
||||||
|
|
||||||
|
align 16
|
||||||
|
|
||||||
mov ecx, CR0_PE
|
mov ecx, CR0_PE
|
||||||
|
|
||||||
; Enabling 32 bit protected mode
|
; Enabling 32 bit protected mode
|
||||||
@ -198,6 +200,20 @@ include "detect/biosdisk.inc"
|
|||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
jmp pword os_code:B32 ; jmp to enable 32 bit mode
|
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
|
align 8
|
||||||
tmp_gdt:
|
tmp_gdt:
|
||||||
|
|
||||||
@ -217,11 +233,37 @@ tmp_gdt:
|
|||||||
dw 11011111b *256 +10010010b
|
dw 11011111b *256 +10010010b
|
||||||
db 0x00
|
db 0x00
|
||||||
|
|
||||||
include "data16.inc"
|
|
||||||
|
|
||||||
use32
|
use32
|
||||||
org $+0x10000
|
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
|
align 4
|
||||||
B32:
|
B32:
|
||||||
mov ax, os_stack ; Selector for os
|
mov ax, os_stack ; Selector for os
|
||||||
@ -269,6 +311,8 @@ B32:
|
|||||||
|
|
||||||
; ENABLE PAGING
|
; ENABLE PAGING
|
||||||
|
|
||||||
|
xchg bx, bx
|
||||||
|
|
||||||
mov eax, sys_pgdir-OS_BASE
|
mov eax, sys_pgdir-OS_BASE
|
||||||
mov cr3, eax
|
mov cr3, eax
|
||||||
|
|
||||||
@ -283,11 +327,6 @@ align 4
|
|||||||
bios32_entry dd ?
|
bios32_entry dd ?
|
||||||
tmp_page_tabs dd ?
|
tmp_page_tabs dd ?
|
||||||
|
|
||||||
use16
|
|
||||||
org $-0x10000
|
|
||||||
include "boot/shutdown.inc" ; shutdown or restart
|
|
||||||
org $+0x10000
|
|
||||||
use32
|
|
||||||
|
|
||||||
__DEBUG__ fix 1
|
__DEBUG__ fix 1
|
||||||
__DEBUG_LEVEL__ fix 1
|
__DEBUG_LEVEL__ fix 1
|
||||||
@ -295,6 +334,31 @@ include 'init.inc'
|
|||||||
|
|
||||||
org OS_BASE+$
|
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
|
align 4
|
||||||
high_code:
|
high_code:
|
||||||
mov ax, os_stack
|
mov ax, os_stack
|
||||||
@ -317,12 +381,12 @@ high_code:
|
|||||||
or ebx, CR4_PGE
|
or ebx, CR4_PGE
|
||||||
mov cr4, ebx
|
mov cr4, ebx
|
||||||
@@:
|
@@:
|
||||||
xor eax, eax
|
; xor eax, eax
|
||||||
mov dword [sys_pgdir], eax
|
; mov dword [sys_pgdir], eax
|
||||||
mov dword [sys_pgdir+4], eax
|
; mov dword [sys_pgdir+4], eax
|
||||||
|
|
||||||
mov eax, cr3
|
; mov eax, cr3
|
||||||
mov cr3, eax ; flush TLB
|
; mov cr3, eax ; flush TLB
|
||||||
|
|
||||||
mov ecx, pg_data.mutex
|
mov ecx, pg_data.mutex
|
||||||
call mutex_init
|
call mutex_init
|
||||||
@ -619,6 +683,8 @@ no_mode_0x12:
|
|||||||
; Try to Initialize APIC
|
; Try to Initialize APIC
|
||||||
call APIC_init
|
call APIC_init
|
||||||
|
|
||||||
|
call LAPIC_init
|
||||||
|
|
||||||
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
|
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
|
||||||
; they are used: when partitions are scanned, hd_read relies on timer
|
; they are used: when partitions are scanned, hd_read relies on timer
|
||||||
call unmask_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