1 |-----------------------------------------------------------
3 | Simple C runtime startup for Human68k
5 | o no stdio support (DOS/IOCS only)
8 | written by Yasha (ITOH Yasufumi)
10 | This file is in the public domain
12 | $NetBSD: start.S,v 1.1 1998/09/01 19:51:56 itohy Exp $
14 #include <machine/asm.h>
16 |-----------------------------------------------------------
21 #define STACK_SIZE 65536 /* stack size in bytes */
26 #define STACK_SYMBOL _stack /* stack top symbol name */
28 #define STACK_SYMBOL stack_8K_hUMAn6 /* has largest hash val on NetBSD ld */
29 #endif /* and will be at the end of bss */
33 #define DUMMY___main 1 /* define dummy __main() for a.out */
36 #ifndef SUPPORT_R_EXEC /* support ".r" relocatable executable */
37 #define SUPPORT_R_EXEC 0 /* (clear bss, don't use a1 at startup) */
38 #endif /* XXX impossible for a.out */
40 #ifndef SUPPORT_HUPAIR
41 #define SUPPORT_HUPAIR 1 /* HUPAIR argument interface support */
45 #define HUPAIR_ARGV0 1 /* use argv[0] passed in HUPAIR manner */
49 #define ADD_PATHNAME 0 /* add command path to argv[0] if not HUPAIR */
52 #ifndef STRICT_SETBLOCK
53 #define STRICT_SETBLOCK 1 /* free unused memory after creating args */
57 #define C_REGPARM 0 /* main() arguments are passed in registers */
58 #endif /* (for gcc -mregparm) */
61 #define NEED_MEMCP 0 /* __memcp: MCB address */
64 #define NEED_PROCP 0 /* __procp: PDB address */
67 #define NEED_VERNUM 1 /* __vernum: Human68k version */
70 #define NEED_PROGNAME 1 /* ___progname: program basename */
73 #define NEED_ENVIRON 1 /* _environ: environment vector */
76 |-----------------------------------------------------------
80 #define DOS(x) .word x
82 #define __FPUTS 0xFF1E
83 #define __VERNUM 0xFF30
84 #define __SETBLOCK 0xFF4A
85 #define __EXIT2 0xFF4C
88 | seed to estimate argument string/vector and environment vector size
89 | (max nohupair argv[0](92+4) + NULLs(8) + alignment(3)) <- donburi?
91 #define estimated_argsz 107
92 #define estimated_com 92 /* estimated command name length (included) */
98 #define char_space 0x20
99 #define char_dquote 0x22
100 #define char_squote 0x27
101 #define char_slash 0x2f
102 #define char_backslash 0x5c
104 #define pdb_mcb 0x10 /* PDB address - MCB address */
105 #define drvpath_pdb 0x070 /* drive and path address - PDB address */
106 #define command_pdb 0x0b4 /* command name address - PDB address */
107 #define top_pdb 0xf0 /* program load address - PDB address */
109 #define stderr 2 /* stderr file handle */
110 #define exit_nomem 127 /* exit status on SETBLOCK failure */
112 |-----------------------------------------------------------
116 | a0: MCB address, a1: program end + 1,
117 | a2: command line, a3: environ, a4: execution start
123 .globl _C_LABEL(main)
126 ASENTRY_NOPROFILE(_start)
128 ASENTRY_NOPROFILE(start)
131 .word 0x611e,0x2348,0x5550,0x4149,0x5200
140 .long 0x72743020,0x56312E31,0x42206279,0x20596173,0x68610000
152 | d3.l: 0xFFFF: hupair, 0x000x: not hupair
156 moveql #char_tab,%d3 | tab (= 9)
157 ishupair: | d3.l: 0: hupair, 9: not hupair
160 | (over)estimate and allocate argument/environ area beforehand
162 addql #1,%a2 | skip byte count
163 moveql #estimated_argsz,%d1 | byte counter
165 moveql #char_space,%d4 | space
171 cmpb %d3,%d0 | tab (if not hupair)
173 acous: addql #4,%d1 | for argv area
177 #if SUPPORT_HUPAIR && HUPAIR_ARGV0
180 moveql #-estimated_com,%d2 | reset argv[0] length
181 moveal %a6,%a4 | preserve argv[0] string address
188 | d1: estimated argument bytes
191 addql #4,%a3 | skip length field
201 | d1: estimated byte count
205 | and ensure the bss/stack (for .r executable) and argument areas valid
207 lea %a0@(pdb_mcb),%a5 | a5: PDB address
210 #define RELOC(sym, reg) lea sym+top_pdb,reg; addl %a5,reg
211 moveal %a1,%a6 | end of data
212 RELOC(_end, %a1) | end of bss
214 pea %a1@(0,%d1:l) | _end + size - pdb
222 bsrs sberr1 | pea %pc@
223 .asciz "setblock failed\r\n"
226 movew #exit_nomem,%a7@
227 DOS(__EXIT2) | _exit(exit_nomem)
231 | here, the bss, stack, and argument/environ areas are certainly valid
236 moveal #STACK_SYMBOL+STACK_SIZE,%a7
253 RELOC(_C_LABEL(_memcp), %a6)
256 movel %a0,_C_LABEL(_memcp)
265 RELOC(_C_LABEL(_procp), %a6)
268 movel %a5,_C_LABEL(_procp)
273 | get version no of Human
278 RELOC(_C_LABEL(_vernum), %a6)
281 movel %d0,_C_LABEL(_vernum)
288 moveal %a1,%a0 | top of argument strings
289 #if SUPPORT_HUPAIR && HUPAIR_ARGV0
294 lea %a5@(drvpath_pdb),%a4 | drive and path name
298 subql #1,%a1 | remove nul char
300 lea %a5@(command_pdb),%a4 | command name
301 arg0lp: moveb %a4@+,%a1@+
306 | find program basename
313 cmpib #char_slash,%d0
315 cmpib #char_backslash,%d0
318 addql #1,%a4 | next of slash
321 RELOC(_C_LABEL(__progname), %a6)
324 movel %a4,_C_LABEL(__progname)
329 | create argument strings
331 moveql #1,%d0 | (d0:l) # arg
333 spskip: moveb %a2@+,%d2
337 cmpb %d3,%d2 | tab (if not hupair)
341 clrb %d1 | no quote here
342 addql #1,%d0 | increment argc
346 cmpib #char_dquote,%d2
348 cmpib #char_squote,%d2
350 quote: moveb %d2,%d1 | save quote character
356 clrb %d1 | quote ended
362 cmpb %d3,%d2 | tab (if not hupair)
369 moveb %d2,%a1@+ | copy char
383 andib #0xfc,%d1 | long alignment
384 moveal %d1,%a1 | argv
386 | a0 is at argument strings
388 movel %a0,%a1@+ | argv[0] ...
398 clrl %a1@+ | argv[argc] should be NULL
411 envend: clrl %a1@+ | NULL termination
413 RELOC(_C_LABEL(environ), %a0)
416 movel %d2,_C_LABEL(environ)
427 DOS(__SETBLOCK) | reset donburi-kanjo (never fails)
436 movel %d2,%a7@- | arg #3 --- envp
439 movel %d1,%a7@- | arg #2 --- argv
440 movel %d0,%a7@- | arg #1 --- argc
444 RELOC(_C_LABEL(main), %a0)
450 #if !C_REGPARM || NEED_ENVIRON
457 #if !defined(__ELF__) && DUMMY___main
458 ENTRY_NOPROFILE(__main)
462 |-----------------------------------------------------------
467 .comm _C_LABEL(_memcp),4
471 .comm _C_LABEL(_procp),4 | PDB address
475 .comm _C_LABEL(_vernum),4
479 .comm _C_LABEL(__progname),4
483 .comm _C_LABEL(environ),4 | environ address
486 |-----------------------------------------------------------
491 .section .stack,"aw",@nobits
496 .comm STACK_SYMBOL,STACK_SIZE