234 lines
4.1 KiB
ArmAsm
234 lines
4.1 KiB
ArmAsm
|
|
/*
|
|
** 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
|
|
|
|
|