Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/sys/go32/crt0.S')
-rw-r--r--newlib/libc/sys/go32/crt0.S233
1 files changed, 233 insertions, 0 deletions
diff --git a/newlib/libc/sys/go32/crt0.S b/newlib/libc/sys/go32/crt0.S
new file mode 100644
index 000000000..5fc6cf77c
--- /dev/null
+++ b/newlib/libc/sys/go32/crt0.S
@@ -0,0 +1,233 @@
+
+/*
+** Called as start(argc, argv, envp)
+*/
+
+/* gs:edx points to prog_info structure. All other registers are OBSOLETE
+** but included for backwards compatibility
+*/
+
+/* These symbols are for global constructors and destructors */
+#if 0
+ .section .ctor
+ .globl ___go32_first_ctor
+___go32_first_ctor:
+ .section .dtor
+ .globl ___go32_last_ctor
+___go32_last_ctor:
+ .globl ___go32_first_dtor
+___go32_first_dtor:
+ .data
+ .globl ___go32_last_dtor
+___go32_last_dtor:
+#endif
+ .text
+ .globl _start
+_start:
+ .globl start
+start:
+#ifdef EMU387
+ pusha
+ push %gs
+#endif
+ movl %eax,__hard_master
+ movl %esi,___pid
+ movl %edi,___transfer_buffer
+ movl %ebx,_ScreenPrimary
+ movl %ebp,_ScreenSecondary
+
+ cmpl $0, %edx
+ je Lcopy_none
+ movw %gs,%cx
+ movw %ds,%ax
+ cmpw %cx,%ax
+ je Lcopy_none
+
+ movl %gs:(%edx), %ecx
+ cmpl __go32_info_block, %ecx
+ jbe Lcopy_less
+ movl __go32_info_block, %ecx
+Lcopy_less:
+ movl $__go32_info_block, %edi
+ addl $3, %ecx
+ andl $0xfffffffc, %ecx
+ movl %ecx, (%edi)
+ addl $4, %edi
+ addl $4, %edx
+ subl $4, %ecx
+Lcopy_more:
+ movl %gs:(%edx), %eax
+ movl %eax, (%edi)
+ addl $4, %edx
+ addl $4, %edi
+ subl $4, %ecx
+ jnz Lcopy_more
+
+ movl __go32_info_block+4, %eax
+ movl %eax, _ScreenPrimary
+ movl __go32_info_block+8, %eax
+ movl %eax, _ScreenSecondary
+/* Backward compatibility - do not copy this one!
+** movl __go32_info_block+12, %eax
+** movl %eax, ___transfer_buffer
+*/
+ movl __go32_info_block+20, %eax
+ movl %eax, ___pid
+ movl __go32_info_block+24, %eax
+ movl %eax, __hard_master
+
+ jmp Lcopy_done
+
+Lcopy_none:
+ movl %ebx,__go32_info_block+4
+ movl %ebp,__go32_info_block+8
+ movl %edi,__go32_info_block+12
+ movl $4096,__go32_info_block+16
+ movl %esi,__go32_info_block+20
+ movl %eax,__go32_info_block+24
+ movl $28, __go32_info_block
+Lcopy_done:
+
+#ifndef EMU387
+ call __setstack
+#endif
+ xorl %esi,%esi
+ xorl %edi,%edi
+ xorl %ebp,%ebp
+ xorl %ebx,%ebx
+
+ movl %esp,%ebx
+#ifdef MAKE_GCRT0
+ call mcount_init /* initialize the profiler */
+#endif
+ movl 8(%ebx),%eax
+ pushl %eax
+ movl %eax,_environ
+ pushl 4(%ebx)
+ pushl (%ebx)
+ call ___main
+ call _main
+ addl $12,%esp
+#ifdef EMU387
+ pop %gs
+ popa
+#else
+ pushl %eax
+ call _exit
+
+exit_again:
+ movl $0x4c00,%eax
+ int $0x21
+ jmp exit_again
+#endif
+
+ ret
+
+
+#ifdef MAKE_GCRT0
+ .globl __exit
+__exit:
+ call mcount_write /* make sure we dump the output */
+exit_again2:
+ movb 4(%esp),%al
+ movb $0x4c,%ah
+ int $0x21
+ jmp exit_again2
+
+/* Here is where we initialize the timer interrupt - specific to go32 */
+/* In this case, the timer calls mcount_isr */
+ .globl mcount_isr_init
+mcount_isr_init:
+ movw __go32_info_block+36, %ax /* run mode */
+ cmp $1,%ax
+ jb skip_mcount
+ cmp $3,%ax
+ ja skip_mcount
+
+ movw $16,%ax
+ movw %ax,%gs
+
+ movzbl __hard_master,%eax /* timer is on irq 0 */
+ shll $3,%eax /* times 8 bpv */
+/* movl $960,%eax vector 0x78 * 8 bpv */
+ movw %gs:(%eax),%cx
+ movw %cx,mc_chain
+ movw %gs:6(%eax),%cx
+ movw %cx,mc_chain_hi
+ movw %gs:2(%eax),%cx
+ movw %cx,mc_chain_sel
+
+ movl $mcount_isr,%ecx
+ movw %cx,%gs:(%eax)
+ movw $0xd8,%gs:2(%eax) /* selector 27 == 32-bit code */
+ movw $0x8f00,%gs:4(%eax)
+ rorl $16,%ecx
+ movw %cx,%gs:6(%eax)
+ movw %ds,%ax
+ movw %ax,%gs
+skip_mcount:
+ movl mcount_histogram,%eax
+ movl $1,(%eax)
+ ret
+
+/* Obtain the PC where we interrupted, and bump the histogram. We should */
+/* do error checking here, but we don't. This routine is specific to go32 */
+/* in some spots */
+mcount_isr:
+ pushl %eax
+ cmpl $1,mcount_skip
+ je L0
+ movl 4(%esp),%eax /* get the PC */
+ subl $0x1020,%eax /* to fit in low..high */
+ andl $0xfffffffc,%eax
+ shrl $1,%eax /* now points to one 4-byte entry */
+ addl mcount_histogram,%eax
+ incw (%eax)
+L0:
+ popl %eax
+ ljmp mc_chain /* chain to the next timer vector */
+ iret
+#endif
+
+ .data
+
+ .globl _environ
+_environ:
+ .long 0
+
+ .globl ___pid
+___pid:
+ .long 42
+
+ .globl ___transfer_buffer
+___transfer_buffer:
+ .long 0
+
+ .globl _ScreenPrimary
+_ScreenPrimary:
+ .long 0
+
+ .globl _ScreenSecondary
+_ScreenSecondary:
+ .long 0
+
+ .globl __hard_master
+ .globl __hard_slave
+ .globl __core_select
+__hard_master:
+ .byte 0
+__hard_slave:
+ .byte 0
+__core_select:
+ .short 0
+
+#ifdef MAKE_GCRT0
+mc_chain:
+ .short 0
+mc_chain_hi:
+ .short 0
+mc_chain_sel:
+ .short 0
+#endif
+
+