fpc/rtl/go32v2/v2prt0.as

939 lines
28 KiB
ActionScript

/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/*****************************************************************************\
* Interface to 32-bit executable (from stub.asm)
*
* cs:eip according to COFF header
* ds 32-bit data segment for COFF program
* fs selector for our data segment (fs:0 is stubinfo)
* ss:sp our stack (ss to be freed)
* <others> All unspecified registers have unspecified values in them.
\*****************************************************************************/
/* modified by Pierre Muller to become the prt0.s for FPC Pascal */
.file "v2prt0.as"
/* #include "stubinfo.h" */
STUBINFO = 0
STUBINFO_MAGIC = 0
STUBINFO_SIZE = 0x10
STUBINFO_MINSTACK = 0x14
STUBINFO_MEMORY_HANDLE = 0x18
STUBINFO_INITIAL_SIZE = 0x1c
STUBINFO_MINKEEP = 0x20
STUBINFO_DS_SELECTOR = 0x22
STUBINFO_DS_SEGMENT = 0x24
STUBINFO_PSP_SELECTOR = 0x26
STUBINFO_CS_SELECTOR = 0x28
STUBINFO_ENV_SIZE = 0x2a
STUBINFO_BASENAME = 0x2c
STUBINFO_ARGV0 = 0x34
STUBINFO_DPMI_SERVER = 0x44
STUBINFO_END = 0x54
/* .comm __stklen, 4
this is added to the compiler so that we can specify
the stack size */
.comm __stkbottom,4
.comm __stubinfo, 4
.comm ___djgpp_base_address, 4
.comm ___djgpp_selector_limit, 4
.comm __crt0_startup_flags, 4
.comm ___djgpp_stack_limit, 4
.lcomm sel_buf, 8
/* ___djgpp_ds_alias defined in go32/exceptn.s */
/* inserted at the end of this file */
/* we use a local copy that will be copied to exceptn.s */
.globl ___v2prt0_ds_alias
___v2prt0_ds_alias:
.long 0
/* allocate 32*4 bytes for RMCB under the $ffff limit for Windows NT */
.globl ___v2prt0_rmcb_regs
___v2prt0_rmcb_regs:
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.data
___djgpp_memory_handle_pointer:
.long ___djgpp_memory_handle_list+8 /* Next free, first for stub */
.comm ___djgpp_memory_handle_list, 2048 /* Enough for 256 handles */
/* simply get current state */
___sbrk_interrupt_state:
.long 0x902
sbrk16_first_byte:
.include "sbrk16.ah"
sbrk16_last_byte:
sbrk16_api_ofs:
.long 0
sbrk16_api_seg:
.word 0
zero:
.long 0
exit16_first_byte:
.include "exit16.ah"
exit16_last_byte:
/* hook_387_emulator:
.long ___emu387_load_hook */
/* this is for when main comes from a library */
.long _main
.text
.globl start
start:
pushl %ds /* set %es same as %ds */
popl %es /* push/pop 4 bytes shorter than ax */
/* Enable NULL pointer protection if DPMI supports it */
testb $0x1, __crt0_startup_flags+1 /* include/crt0.h */
jnz 1f
movl $start, %eax
cmpl $0x1000, %eax
jl 1f
movw $0x507, %ax
.byte 0x64 /* fs: */
movl STUBINFO_MEMORY_HANDLE, %esi
xorl %ebx, %ebx /* Offset 0 in mem block */
movl $1, %ecx /* Set one page */
movl $zero, %edx
int $0x31 /* Make null page uncommitted */
jnc 1f
call v2prt0_windows
1:
/* Create an alias for DS to be used by real-mode callbacks (exception handler messes with DS itself) */
movw %ds, %bx
movw $0x000a, %ax
int $0x31
jnc .Lds_alias_ok
movb $0x4c, %ah
int $0x21
.Lds_alias_ok:
movw %ax, ___v2prt0_ds_alias
movl %eax, %ebx
movw $0x0009, %ax
movw %cs, %cx /* get CPL from %cs */
andl $3, %ecx
shll $5, %ecx /* move it into place */
orw $0xc093, %cx
int $0x31 /* set access rights for alias */
/* Maybe set our DS limit to 4Gb in size if flag set */
testb $0x80, __crt0_startup_flags /* include/crt0.h */
jz 2f
movw $0xffff, %cx
movl %ecx, %edx
movw $0x0008, %ax /* reset alias limit to -1 */
int $0x31
movw %cs, %bx
movw $0x0008, %ax /* reset DS limit to -1 */
int $0x31
movw %ds, %bx
movw $0x0008, %ax /* reset DS limit to -1 */
int $0x31
lsl %ebx, %ebx /* Should be -1 */
incl %ebx
jz 2f
andb $0x7f, __crt0_startup_flags /* clear it if failure */
2:
/* Allocate some DOS memory and copy our sbrk helper into it. */
movl $sbrk16_first_byte, %esi
movzwl 8(%esi), %ebx
shrl $4, %ebx
movw $0x0100, %ax
int $0x31
jnc .Ldos_alloc_ok
movb $0x4c, %ah
int $0x21
.Ldos_alloc_ok:
movw %cs, 2(%esi)
/* store API information */
movw %ds, 4(%esi)
movw %dx, 6(%esi)
/* selector for allocated block */
movzwl (%esi), %eax /* calculate API address */
movl %eax, sbrk16_api_ofs
pushl %es /* move the data */
movw %dx, %es
movl $(sbrk16_last_byte - sbrk16_first_byte), %ecx
shrl $2,%ecx
xorl %edi, %edi
cld
rep
movsl
popl %es
movl %edx, %ebx /* dos memory selector */
movw $0x000b, %ax /* get descriptor */
movl $sel_buf, %edi
int $0x31
andb $0xbf, sel_buf+6 /* make 16-bit */
andb $0xf0, sel_buf+5 /* remove old type */
orb $0x0a, sel_buf+5 /* set new type to code/read */
xorl %eax, %eax /* allocate new selector */
movw $0x0001, %cx
int $0x31
movw %ax, sbrk16_api_seg
movl %eax, %ebx
movw $0x000c, %ax /* set descriptor */
movl $sel_buf, %edi
int $0x31
/* Initialize the brk/sbrk variables */
/* movl $end, __what_size_app_thinks_it_is */
.byte 0x64 /* fs: */
movl STUBINFO_INITIAL_SIZE, %eax
movl %eax, __what_size_dpmi_thinks_we_are
/* Maybe lock the initial block, expects BX:CX */
movl %ecx,%ebx
movl %edx,%ecx
addw $4096,%cx /* Skip null page */
adcl $0,%ebx
subl $4096,%eax
pushl %eax
call lock_memory
.byte 0x64 /* fs: */
movl STUBINFO_MEMORY_HANDLE, %eax
movl %eax, ___djgpp_memory_handle_list
.byte 0x64 /* fs: */ /* copy stubinfo into local memory */
movl STUBINFO_SIZE, %eax
pushl %eax
call ___sbrk
movl %eax, __stubinfo
movl %eax,operatingsystem_stub_info
movl %eax, %edi
.byte 0x64 /* fs: */
movl STUBINFO_SIZE, %ecx
shrl $2, %ecx
xorl %esi, %esi /* Zero */
pushl %ds
pushl %fs
popl %ds
cld
rep
movsl
popl %ds
movl __stklen, %eax /* get program-requested stack size */
.byte 0x64 /* fs: */
movl STUBINFO_MINSTACK, %ecx /* get stub-requested stack size */
cmpl %ecx, %eax
jge .Luse_stubinfo_stack_size /* use the larger of the two */
movl %ecx, %eax
movl %eax, __stklen /* store the actual stack length */
.Luse_stubinfo_stack_size:
pushl %eax
call ___sbrk /* allocate the memory */
cmpl $-1, %eax
je .Lno_memory
movl %eax, ___djgpp_stack_limit /* Bottom of stack */
addl $256,%eax
movl %eax,__stkbottom /* for stack checks */
/* movl %eax,operatingsystem_stackbottom */
/* StackBottom is
a ThrteadVar and can not be given a symbol with name,
copying value of __stkbottom to system.STackBottom variable
is done in system unit startup code. PM */
movl ___djgpp_stack_limit,%eax /* Bottom of stack */
addl __stklen, %eax
movw %ds, %dx /* set stack */
movw %dx, %ss
andl $0xfffffffc,%eax
movl %eax, %esp
xorl %ebp, %ebp
call ___prt1_startup /* run program */
jmp exit
.Lno_memory:
movb $0xff, %al
jmp exit
/*-----------------------------------------------------------------------------*/
/* #define FREESEL(x) movw x, %bx; movw $0x0001, %ax; int $0x31 */
.macro FREESEL x
movw \x,%bx
movw $0x0001,%ax
int $0x31
.endm
.global ___exit
.align 2
___exit:
/* special exit from dpmiexcp.c */
.global __exit
__exit:
movl 4(%esp),%eax
exit:
movl %eax,%ecx
xorl %eax,%eax
movw %ax,%fs
movw %ax,%gs
cmpl $0,_exception_exit
jz .Lno_exception
pushl %ecx
call *_exception_exit
popl %ecx
.Lno_exception:
cli /* Just in case they didn't unhook ints */
FREESEL operatingsystem_go32_info_block+26 /* selector for linear memory */
FREESEL ___v2prt0_ds_alias /* DS alias for rmcb exceptions */
FREESEL sbrk16_api_seg /* sbrk cs */
movw sbrk16_first_byte+6,%dx /* selector for allocated DOS mem */
movw $0x101, %ax
int $0x31 /* Free block and selector */
9:
movl __stubinfo, %edx
movl STUBINFO_CS_SELECTOR(%edx), %eax
movw %ax, sbrk16_api_seg
xorl %edi, %edi
movl %edi, sbrk16_api_ofs /* Offset is zero */
movw STUBINFO_DS_SELECTOR(%edx), %es
movb %cl, %dl /* Exit status */
movl $exit16_first_byte, %esi
movl $(exit16_last_byte - exit16_first_byte), %ecx
cld
rep
movsb
movw %es,%ax /* We will free stack! */
movw %ax,%ss
movl $0x400,%esp /* Transfer buffer >= 1024 bytes */
xorl %ebp, %ebp /* V1.10 bug fix */
movl ___djgpp_memory_handle_list, %edi
movl ___djgpp_memory_handle_list+2, %esi /* Skip word prefixes */
FREESEL %ds
movw %cs, %bx
/* Call exit procedure with BX=32-bit CS; SI+DI=32-bit handle; DL=exit status */
.byte 0x2e
ljmp sbrk16_api_ofs
/*-----------------------------------------------------------------------------*/
/* .lcomm __what_size_app_thinks_it_is, 4 */
__what_size_app_thinks_it_is:
.long end
.lcomm __what_we_return_to_app_as_old_size, 4
.lcomm __what_size_dpmi_thinks_we_are, 4
lock_memory:
/* BX:CX should be linear address; size is pushed on stack */
testb $0x10, __crt0_startup_flags+1 /* include/crt0.h */
jz 13f
pushl %esi
pushl %edi
pushl %eax
movl 16(%esp),%edi
movw 18(%esp),%si
movw $0x600,%ax
int $0x31
popl %eax
popl %edi
popl %esi
13: ret $4 /* Pop the argument */
.global ___sbrk
.align 2
___sbrk:
movl __what_size_app_thinks_it_is, %eax
movl 4(%esp), %ecx /* Increment size */
addl %ecx, %eax
jnc .Lbrk_common
/* Carry is only set if a negative increment or wrap happens. Negative
increment is semi-OK, wrap (only for multiple zone sbrk) isn't. */
test $0x80000000, %ecx /* Clears carry */
jnz .Lbrk_common
stc /* Put carry back */
jmp .Lbrk_common
.globl ___brk
.align 2
___brk:
movl 4(%esp), %eax
clc
.Lbrk_common:
pushl %esi
pushl %edi
pushl %ebx
movl __what_size_app_thinks_it_is, %edx /* save info */
movl %edx, __what_we_return_to_app_as_old_size
movl %eax, __what_size_app_thinks_it_is
/* multi code is not present */
/* jc 10f Wrap for multi-zone */
cmpl __what_size_dpmi_thinks_we_are, %eax /* don't bother shrinking */
jbe .Lbrk_nochange
addl $0x0000ffff, %eax /* round up to 64K block */
andl $0xffff0000, %eax
push %eax /* size - save for later */
movl ___djgpp_memory_handle_list, %edi /* request new size */
movw ___djgpp_memory_handle_list+2, %si
movl %eax, %ecx /* size not limit */
movl %eax, %ebx /* size not limit */
shrl $16, %ebx /* BX:CX size */
movw $0x0900, %ax /* disable interrupts */
int $0x31
movl %eax,___sbrk_interrupt_state
lcall sbrk16_api_ofs
setc %dl /* Save carry */
/* popl %eax restore interrupts
int $0x31 postponed after ds alias is set correctly */
test %dl,%dl
popl %edx
jne .Lbrk_error
movl %edi, ___djgpp_memory_handle_list /* store new handle */
movw %si, ___djgpp_memory_handle_list+2
movl %ecx, ___djgpp_base_address /* store new base address */
movw %bx, ___djgpp_base_address+2
movl %edx, %eax
movl __what_size_dpmi_thinks_we_are, %ecx
subl %ecx, %eax
addl ___djgpp_base_address, %ecx
movl %ecx, %ebx
shrl $16, %ebx /* BX:CX addr */
pushl %eax /* Size */
call lock_memory
decl %edx /* limit now, not size */
5: movl %edx, ___djgpp_selector_limit
orw $0x0fff, %dx /* low bits set */
movw $0x0008, %ax /* reset CS limit */
movw %cs, %bx
movl %edx, %ecx
shrl $16, %ecx
int $0x31 /* CX:DX is limit */
testb $0x80, __crt0_startup_flags /* include/crt0.h */
jnz 3f
movw $0x0008, %ax /* reset DS limit */
movw %ds, %bx
int $0x31
movw $0x0008, %ax /* reset DS alias limit */
movl ___v2prt0_ds_alias, %ebx
int $0x31
3:
movw $0x0007, %ax /* reset DS alias base */
movl ___v2prt0_ds_alias, %ebx
movl ___djgpp_base_address, %edx
movw ___djgpp_base_address+2, %cx
int $0x31
movl ___sbrk_interrupt_state,%eax /* restore interrupts */
int $0x31
movl ___djgpp_selector_limit, %edx
12: incl %edx /* Size not limit */
testb $0x60, __crt0_startup_flags /* include/crt0.h */
jz .Lno_fill_sbrk_memory
pushl %ds
popl %es
movl __what_size_dpmi_thinks_we_are, %edi /* set all newly resized bytes zero */
movl %edx, %ecx /* Limit */
subl %edi, %ecx /* Adjust count for base */
xorl %eax, %eax
testb $0x40, __crt0_startup_flags
jz .Lno_deadbeef
movl $0xdeadbeef, %eax /* something really easy to spot */
.Lno_deadbeef:
shrl $2, %ecx /* div 4 Longwords not bytes */
cld
rep
stosl
.Lno_fill_sbrk_memory:
movl %edx, __what_size_dpmi_thinks_we_are
.Lbrk_nochange: /* successful return */
movl __what_we_return_to_app_as_old_size, %eax
jmp .Lbrk_return
.Lbrk_error: /* error return */
movl __what_we_return_to_app_as_old_size, %eax
movl %eax, __what_size_app_thinks_it_is
movl $0, %eax
.Lbrk_return:
popl %ebx
popl %edi
popl %esi
ret
/* From here on this are parts of crt1.c converted to assembler
and without any call to libc, so that it works without anything else
additions made by Pierre Muller*/
/* from dpmidefs.h * /
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/* from include <libc/asmdefs.h> */
/* all macros removed here */
/* #define FUNC(x) .globl x; x: */
/* #define ENTER pushl %ebp; movl %esp,%ebp */
/* #define LEAVE(x) movl %ebp,%esp; popl %ebp; ret $(x) */
/* #define ARG1 8(%ebp)
#define ARG1h 10(%ebp)
#define ARG2 12(%ebp)
#define ARG2h 14(%ebp)
#define ARG3 16(%ebp)
#define ARG4 20(%ebp)
#define ARG5 24(%ebp)
#define ARG6 28(%ebp)
#define ARG7 32(%ebp)
#define ARG8 36(%ebp) */
.comm ___dpmi_error,2
/* from dpmi0000.s */
/* .globl ___dpmi_allocate_ldt_descriptors */
/* using pascal convention => not usabel by C code */
___dpmi_allocate_ldt_descriptors:
pushl %ebp; movl %esp,%ebp
movl 8(%ebp), %ecx
movl $0x0000, %eax
int $0x31
jnc .L_noerror0000
movw %ax,___dpmi_error
movl $-1,%eax
jmp .L_leave0000
.L_noerror0000:
movzwl %ax,%eax
.L_leave0000:
movl %ebp,%esp
popl %ebp
ret $4
/* from file dpmi0008.s */
/* .globl ___dpmi_set_segment_limit */
___dpmi_set_segment_limit:
pushl %ebp; movl %esp,%ebp
movl 8(%ebp), %ebx
movzwl 12(%ebp), %edx
movzwl 14(%ebp),%ecx
movl $0x0008,%eax
int $0x31
jnc .L_noerror0008
movw %ax,___dpmi_error
movl $-1,%eax
jmp .L_leave0008
.L_noerror0008:
xorl %eax,%eax
.L_leave0008:
movl %ebp,%esp
popl %ebp
ret $8
/* .globl ___dpmi_get_version */
___dpmi_get_version:
pushl %ebp; movl %esp,%ebp
movl $0x0400,%eax
int $0x31
jnc .L_noerror0400
movw %ax,___dpmi_error
movl $-1,%eax
jmp .L_leave0400
.L_noerror0400:
movl 8(%ebp), %esi
movb %ah, (%esi)
movb %al, 1(%esi)
movw %bx, 2(%esi)
movb %cl, 4(%esi)
movb %dh, 5(%esi)
movb %dl, 6(%esi)
xorl %eax,%eax
.L_leave0400:
movl %ebp,%esp
popl %ebp
ret $4
_set_os_trueversion:
pushl %ebp
movl %esp,%ebp
movl $0x3306,%eax
xorl %ebx,%ebx
int $0x21
movzbl %bl,%eax
shll $8,%eax
shrl $8,%ebx
andl $0xff,%ebx
addl %ebx,%eax
movw %ax,__os_trueversion
popl %ebp
ret
/* .globl ___dpmi_get_segment_base_address*/
___dpmi_get_segment_base_address:
pushl %ebp; movl %esp,%ebp
movl 8(%ebp), %ebx
movl $0x0006,%eax
int $0x31
jnc .L_noerror0006
movw %ax,___dpmi_error
movl $-1,%eax
jmp .L_leave0006
.L_noerror0006:
movl 12(%ebp), %ebx
movl %edx, (%ebx)
movw %cx, 2(%ebx)
xorl %eax,%eax
.L_leave0006:
movl %ebp,%esp
popl %ebp
ret $8
.globl ___bss_count
.data
.align 2
___bss_count:
.long 1
.text
.align 2
.globl _setup_core_selector
_setup_core_selector:
pushl %ebp
movl %esp,%ebp
pushl $1
call ___dpmi_allocate_ldt_descriptors
/* addl $4,%esp */
cmpl $-1,%eax
jne .L24
movw $0,operatingsystem_go32_info_block+26
leave
ret
.align 2,0x90
.L24:
movw %ax,operatingsystem_go32_info_block+26
movw %ax,_core_selector
pushl $0x10ffff
andl $0xffff,%eax
pushl %eax
call ___dpmi_set_segment_limit
leave
ret
.align 2
.globl _setup_screens
_setup_screens:
pushl %ebp
movl %esp,%ebp
movw operatingsystem_go32_info_block+26,%dx
movl $1048563,%ecx
/APP
movw %dx, %gs
.byte 0x65
movw (%ecx),%ax
/NO_APP
cmpw $64896,%ax
jne .L26
movl $655360,operatingsystem_go32_info_block+8
movl $655360,operatingsystem_go32_info_block+4
leave
ret
.align 2,0x90
.L26:
movl $1097,%ecx
/APP
movw %dx,%gs
.byte 0x65
movb (%ecx),%al
/NO_APP
cmpb $7,%al
jne .L29
movl $720896,operatingsystem_go32_info_block+4
movl $753664,operatingsystem_go32_info_block+8
leave
ret
.align 2,0x90
.L29:
movl $753664,operatingsystem_go32_info_block+4
movl $720896,operatingsystem_go32_info_block+8
leave
ret
.align 2
.globl _setup_go32_info_block
_setup_go32_info_block:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
leal -8(%ebp),%eax
pushl %eax
call ___dpmi_get_version
movl $40,operatingsystem_go32_info_block
movl __stubinfo,%edx
movzwl 36(%edx),%eax
sall $4,%eax
movl %eax,operatingsystem_go32_info_block+12
movzwl 32(%edx),%ecx
movl %ecx,operatingsystem_go32_info_block+16
movzwl 38(%edx),%ecx
movl %ecx,operatingsystem_go32_info_block+20
movb -3(%ebp),%al
movb %al,operatingsystem_go32_info_block+24
movb -2(%ebp),%al
movb %al,operatingsystem_go32_info_block+25
movl $-1,operatingsystem_go32_info_block+28
pushl $operatingsystem_go32_info_block+32
movzwl 38(%edx),%eax
pushl %eax
call ___dpmi_get_segment_base_address
movw $4,operatingsystem_go32_info_block+36
movb -8(%ebp),%dl
salw $8,%dx
movzbw -7(%ebp),%ax
orw %ax,%dx
movw %dx,operatingsystem_go32_info_block+38
call copy_to_c_go32_info_block
leave
ret
copy_to_c_go32_info_block:
leal operatingsystem_go32_info_block,%esi
leal __go32_info_block,%edi
movl $10,%ecx
rep
movsl
ret
.data
/* fpu codeword */
___fpucw:
.long 0x1332
/* __go32_info_block for C programs */
.align 2
.globl __go32_info_block
.comm __go32_info_block,40
/*
-- prt1_startup --
*/
.text
.align 2
.globl ___prt1_startup
___prt1_startup:
pushl %ebp
movl %esp,%ebp
pushl %ebx
incl ___bss_count
movl $0,___crt0_argv
call _set_os_trueversion
call _setup_core_selector
call _setup_screens
call _setup_go32_info_block
incl ___environ_changed
/* call set_processor emulation */
/* neede to avoid FPU exception if calling from anothe DPMI program */
movl $0xe01,%eax
movl $1,%ebx
int $0x31
fninit /* initialize fpu */
push %eax /* Dummy for status store check */
movl %esp,%esi
movw $0x5a5a,(%esi)
/* fwait maybe this one is responsible of exceptions */
fnstsw (%esi)
cmpb $0,(%esi)
jne .Lno_387
fldcw ___fpucw
.Lno_387:
popl %eax
pushl operatingsystem_parameter_envp
pushl ___crt0_argv
pushl ___crt0_argc
call _pascal_start
pushl %eax
/* call _exit changed to */
call exit
.align 2,0x90
/* .comm dos_argv0,4 */
.comm ___dos_argv0,4
.comm ___crt0_argc,4
.comm ___crt0_argv,4
.comm ___environ_changed,4
/* ___environ_changed: not in data because it is defined in putenv.c */
/* .long 0 */
.globl _exception_exit
_exception_exit:
.long 0
.globl _swap_in
_swap_in:
.long 0
.globl _swap_out
_swap_out:
.long 0
.global _v2prt0_exceptions_on
_v2prt0_exceptions_on:
.long 0
// Fill null page with NOPs
// and a jmp windows_error at the end
.globl v2prt0_windows
v2prt0_windows:
movl $0x90909090,%eax
xorl %edi,%edi
movl $0x400,%ecx
cld
rep
stosl
movl $0xffB,%edi
movb $0xe9,%al
stosb
movl $_fpc_windows_error-4,%eax
subl %edi,%eax
stosl
ret
// Raise SIGILL with UD2 opcode
.globl _fpc_windows_error
_fpc_windows_error:
cmpl $0,_exception_exit
je .L_error_216
.byte 0x0f,0x0b
.L_error_216:
pushl $216
call __exit
jmp exit
#enif
/* this was the prt0.s from the go32v1 version */
//
// call as start(argc, argv, envp) (C-calling convention)
//
.globl _pascal_start
_pascal_start:
/* %ebx doesn't contain ScreenPrimary */
movl operatingsystem_go32_info_block+4,%ebx
movl %ebx,_ScreenPrimary
/* core selector in %fs */
/* keep original fs for debuggers !!!!! (PM) */
movw %fs,%ax
movw %ax,___v2prt0_start_fs
movw _core_selector,%ax
movw %ax,%fs
// Top of frame
movl $0x0,%ebp
movl %esp,%ebx
movl 12(%ebx),%eax
movl %eax,operatingsystem_parameter_envp
movl %eax,__environ
movl %eax,_environ
movl 8(%ebx),%eax
movl %eax,_args
movl 4(%ebx),%eax
movl %eax,_argc
call PASCALMAIN
movl $0,%eax
/* no error if passing here */
/* movl $0x4c00,%eax
int $0x21 */
ret
.data
/* .comm operatingsystem_parameter_envp,4 */
.globl _ScreenPrimary
_ScreenPrimary:
.long 0
.globl _argc
_argc:
.long 0
.globl _args
_args:
.long 0
.globl _run_mode
_run_mode:
.word 4
.globl _core_selector
_core_selector:
.word 0
.globl ___v2prt0_start_fs
___v2prt0_start_fs:
.word 0
/* DJGPP CVS crt1.c code uses __environ symbol */
/* corresponding to _environ C variable */
/* instead of _environ symbol since commit rev 1.11 */
/* Thu Aug 19 9:11:52 2004 UTC by peuha */
/* Provide both here to avoid crt1.o loading. */
.comm __environ,4
.comm _environ,4
/* Here Pierre Muller added all what was in crt1.c */
/* in assembler */
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/* adapted to assembler for FPC by Pierre Muller */
/* Global variables */
/* This gets incremented each time the program is started.
Programs (such as Emacs) which dump their code to create
a new executable, cause this to be larger than 2. Library
functions that cache info in static variables should check
the value of `__bss_count' if they need to reinitialize
the static storage. */
.data
.globl ___bss_count
___bs_count:
.long 1
.globl __dos_ds
__dos_ds:
.long 0
.globl ___PROXY
___PROXY:
.ascii " !proxy"
.byte 0
.globl ___PROXY_LEN
___PROXY_LEN:
.long 7
.comm __os_trueversion,2