1 1.1 itohy |----------------------------------------------------------- 2 1.1 itohy | 3 1.1 itohy | Simple C runtime startup for Human68k 4 1.1 itohy | 5 1.1 itohy | o no stdio support (DOS/IOCS only) 6 1.1 itohy | o HUPAIR support 7 1.1 itohy | 8 1.3 itohy | written by ITOH Yasufumi 9 1.1 itohy | 10 1.1 itohy | This file is in the public domain 11 1.1 itohy | 12 1.4 isaki | $NetBSD: start.S,v 1.4 2024/01/07 07:58:34 isaki Exp $ 13 1.2 itohy 14 1.2 itohy #include <machine/asm.h> 15 1.1 itohy 16 1.1 itohy |----------------------------------------------------------- 17 1.1 itohy | 18 1.1 itohy | configuration 19 1.1 itohy | 20 1.1 itohy #ifndef STACK_SIZE 21 1.1 itohy #define STACK_SIZE 65536 /* stack size in bytes */ 22 1.1 itohy #endif 23 1.1 itohy 24 1.1 itohy #ifndef STACK_SYMBOL 25 1.2 itohy #ifdef __ELF__ 26 1.2 itohy #define STACK_SYMBOL _stack /* stack top symbol name */ 27 1.2 itohy #else /* a.out */ 28 1.1 itohy #define STACK_SYMBOL stack_8K_hUMAn6 /* has largest hash val on NetBSD ld */ 29 1.1 itohy #endif /* and will be at the end of bss */ 30 1.2 itohy #endif 31 1.1 itohy 32 1.1 itohy #ifndef DUMMY___main 33 1.2 itohy #define DUMMY___main 1 /* define dummy __main() for a.out */ 34 1.1 itohy #endif 35 1.1 itohy 36 1.1 itohy #ifndef SUPPORT_R_EXEC /* support ".r" relocatable executable */ 37 1.1 itohy #define SUPPORT_R_EXEC 0 /* (clear bss, don't use a1 at startup) */ 38 1.1 itohy #endif /* XXX impossible for a.out */ 39 1.1 itohy 40 1.1 itohy #ifndef SUPPORT_HUPAIR 41 1.1 itohy #define SUPPORT_HUPAIR 1 /* HUPAIR argument interface support */ 42 1.1 itohy #endif 43 1.1 itohy 44 1.1 itohy #ifndef HUPAIR_ARGV0 45 1.1 itohy #define HUPAIR_ARGV0 1 /* use argv[0] passed in HUPAIR manner */ 46 1.1 itohy #endif 47 1.1 itohy 48 1.1 itohy #ifndef ADD_PATHNAME 49 1.1 itohy #define ADD_PATHNAME 0 /* add command path to argv[0] if not HUPAIR */ 50 1.1 itohy #endif 51 1.1 itohy 52 1.1 itohy #ifndef STRICT_SETBLOCK 53 1.1 itohy #define STRICT_SETBLOCK 1 /* free unused memory after creating args */ 54 1.1 itohy #endif 55 1.1 itohy 56 1.1 itohy #ifndef C_REGPARM 57 1.1 itohy #define C_REGPARM 0 /* main() arguments are passed in registers */ 58 1.1 itohy #endif /* (for gcc -mregparm) */ 59 1.1 itohy 60 1.1 itohy #ifndef NEED_MEMCP 61 1.1 itohy #define NEED_MEMCP 0 /* __memcp: MCB address */ 62 1.1 itohy #endif 63 1.1 itohy #ifndef NEED_PROCP 64 1.1 itohy #define NEED_PROCP 0 /* __procp: PDB address */ 65 1.1 itohy #endif 66 1.1 itohy #ifndef NEED_VERNUM 67 1.1 itohy #define NEED_VERNUM 1 /* __vernum: Human68k version */ 68 1.1 itohy #endif 69 1.1 itohy #ifndef NEED_PROGNAME 70 1.1 itohy #define NEED_PROGNAME 1 /* ___progname: program basename */ 71 1.1 itohy #endif 72 1.1 itohy #ifndef NEED_ENVIRON 73 1.1 itohy #define NEED_ENVIRON 1 /* _environ: environment vector */ 74 1.1 itohy #endif 75 1.1 itohy 76 1.1 itohy |----------------------------------------------------------- 77 1.1 itohy | 78 1.1 itohy | DOS call 79 1.1 itohy | 80 1.1 itohy #define DOS(x) .word x 81 1.1 itohy 82 1.1 itohy #define __FPUTS 0xFF1E 83 1.1 itohy #define __VERNUM 0xFF30 84 1.1 itohy #define __SETBLOCK 0xFF4A 85 1.1 itohy #define __EXIT2 0xFF4C 86 1.1 itohy 87 1.4 isaki | 88 1.1 itohy | seed to estimate argument string/vector and environment vector size 89 1.1 itohy | (max nohupair argv[0](92+4) + NULLs(8) + alignment(3)) <- donburi? 90 1.4 isaki | 91 1.1 itohy #define estimated_argsz 107 92 1.1 itohy #define estimated_com 92 /* estimated command name length (included) */ 93 1.1 itohy 94 1.1 itohy | 95 1.1 itohy | other constants 96 1.1 itohy | 97 1.1 itohy #define char_tab 0x09 98 1.1 itohy #define char_space 0x20 99 1.1 itohy #define char_dquote 0x22 100 1.1 itohy #define char_squote 0x27 101 1.1 itohy #define char_slash 0x2f 102 1.1 itohy #define char_backslash 0x5c 103 1.1 itohy 104 1.1 itohy #define pdb_mcb 0x10 /* PDB address - MCB address */ 105 1.1 itohy #define drvpath_pdb 0x070 /* drive and path address - PDB address */ 106 1.1 itohy #define command_pdb 0x0b4 /* command name address - PDB address */ 107 1.1 itohy #define top_pdb 0xf0 /* program load address - PDB address */ 108 1.1 itohy 109 1.1 itohy #define stderr 2 /* stderr file handle */ 110 1.1 itohy #define exit_nomem 127 /* exit status on SETBLOCK failure */ 111 1.1 itohy 112 1.1 itohy |----------------------------------------------------------- 113 1.1 itohy | 114 1.1 itohy | execution start 115 1.1 itohy | 116 1.1 itohy | a0: MCB address, a1: program end + 1, 117 1.1 itohy | a2: command line, a3: environ, a4: execution start 118 1.1 itohy | 119 1.1 itohy |.cpu 68000 120 1.1 itohy .text 121 1.1 itohy .even 122 1.1 itohy 123 1.2 itohy .globl _C_LABEL(main) 124 1.1 itohy 125 1.2 itohy #ifdef __ELF__ 126 1.2 itohy ASENTRY_NOPROFILE(_start) 127 1.2 itohy #else 128 1.2 itohy ASENTRY_NOPROFILE(start) 129 1.2 itohy #endif 130 1.1 itohy #if SUPPORT_HUPAIR 131 1.1 itohy .word 0x611e,0x2348,0x5550,0x4149,0x5200 132 1.1 itohy #else 133 1.1 itohy .word 0x6016 134 1.1 itohy #endif 135 1.1 itohy #if SUPPORT_R_EXEC 136 1.1 itohy .word 0x7263 137 1.1 itohy #else 138 1.1 itohy .word 0x7863 139 1.1 itohy #endif 140 1.1 itohy .long 0x72743020,0x56312E31,0x42206279,0x20596173,0x68610000 141 1.1 itohy 142 1.1 itohy | 143 1.1 itohy | check if hupair 144 1.1 itohy | 145 1.1 itohy #if SUPPORT_HUPAIR 146 1.2 itohy moveal %a7@+,%a4 147 1.2 itohy lea %a2@(-8),%a6 148 1.2 itohy moveql #7,%d3 149 1.1 itohy chkhupair: 150 1.2 itohy cmpmb %a6@+,%a4@+ 151 1.2 itohy dbne %d3,chkhupair 152 1.1 itohy | d3.l: 0xFFFF: hupair, 0x000x: not hupair 153 1.2 itohy addqw #1,%d3 154 1.1 itohy beqs ishupair 155 1.1 itohy #endif 156 1.2 itohy moveql #char_tab,%d3 | tab (= 9) 157 1.1 itohy ishupair: | d3.l: 0: hupair, 9: not hupair 158 1.1 itohy 159 1.1 itohy | 160 1.1 itohy | (over)estimate and allocate argument/environ area beforehand 161 1.1 itohy | 162 1.2 itohy addql #1,%a2 | skip byte count 163 1.2 itohy moveql #estimated_argsz,%d1 | byte counter 164 1.2 itohy moveal %a2,%a6 165 1.2 itohy moveql #char_space,%d4 | space 166 1.2 itohy acou1: addql #1,%d1 167 1.2 itohy moveb %a6@+,%d0 168 1.1 itohy beqs acou2 169 1.2 itohy cmpb %d4,%d0 | space 170 1.1 itohy beqs acous 171 1.2 itohy cmpb %d3,%d0 | tab (if not hupair) 172 1.1 itohy bnes acou1 173 1.2 itohy acous: addql #4,%d1 | for argv area 174 1.1 itohy bras acou1 175 1.1 itohy 176 1.1 itohy acou2: 177 1.1 itohy #if SUPPORT_HUPAIR && HUPAIR_ARGV0 178 1.2 itohy tstb %d3 179 1.1 itohy bnes anohp 180 1.2 itohy moveql #-estimated_com,%d2 | reset argv[0] length 181 1.2 itohy moveal %a6,%a4 | preserve argv[0] string address 182 1.2 itohy acouhp: addql #1,%d2 183 1.2 itohy tstb %a6@+ 184 1.1 itohy bnes acouhp 185 1.2 itohy addl %d2,%d1 186 1.1 itohy anohp: 187 1.1 itohy #endif 188 1.1 itohy | d1: estimated argument bytes 189 1.1 itohy 190 1.1 itohy #if NEED_ENVIRON 191 1.2 itohy addql #4,%a3 | skip length field 192 1.2 itohy moveal %a3,%a6 193 1.2 itohy ecou1: addql #4,%d1 194 1.2 itohy tstb %a6@+ 195 1.1 itohy beqs ecoue 196 1.2 itohy ecou2: tstb %a6@+ 197 1.1 itohy bnes ecou2 198 1.1 itohy bras ecou1 199 1.1 itohy ecoue: 200 1.1 itohy #endif 201 1.1 itohy | d1: estimated byte count 202 1.1 itohy 203 1.1 itohy | 204 1.1 itohy | free memory 205 1.1 itohy | and ensure the bss/stack (for .r executable) and argument areas valid 206 1.1 itohy | 207 1.2 itohy lea %a0@(pdb_mcb),%a5 | a5: PDB address 208 1.2 itohy subl %a5,%d1 209 1.1 itohy #if SUPPORT_R_EXEC 210 1.2 itohy #define RELOC(sym, reg) lea sym+top_pdb,reg; addl %a5,reg 211 1.2 itohy moveal %a1,%a6 | end of data 212 1.2 itohy RELOC(_end, %a1) | end of bss 213 1.1 itohy #endif 214 1.2 itohy pea %a1@(0,%d1:l) | _end + size - pdb 215 1.2 itohy movel %a5,%a7@- 216 1.1 itohy DOS(__SETBLOCK) 217 1.2 itohy tstl %d0 218 1.1 itohy bpls sbnoerr 219 1.1 itohy 220 1.1 itohy setblock_err: 221 1.2 itohy movew #stderr,%a7@ 222 1.2 itohy bsrs sberr1 | pea %pc@ 223 1.1 itohy .asciz "setblock failed\r\n" 224 1.1 itohy .even 225 1.1 itohy sberr1: DOS(__FPUTS) 226 1.2 itohy movew #exit_nomem,%a7@ 227 1.1 itohy DOS(__EXIT2) | _exit(exit_nomem) 228 1.1 itohy 229 1.1 itohy sbnoerr: 230 1.1 itohy 231 1.1 itohy | here, the bss, stack, and argument/environ areas are certainly valid 232 1.1 itohy 233 1.1 itohy | 234 1.1 itohy | set stack 235 1.1 itohy | 236 1.2 itohy moveal #STACK_SYMBOL+STACK_SIZE,%a7 237 1.1 itohy 238 1.1 itohy #if SUPPORT_R_EXEC 239 1.1 itohy | 240 1.1 itohy | clear bss section 241 1.1 itohy | 242 1.1 itohy loop_clrbss: 243 1.2 itohy clrl %a6@+ 244 1.2 itohy cmpal %a1,%a6 245 1.1 itohy bcss loop_clrbss 246 1.1 itohy #endif 247 1.1 itohy 248 1.1 itohy | 249 1.1 itohy | save MCB address 250 1.1 itohy | 251 1.1 itohy #if NEED_MEMCP 252 1.1 itohy # if SUPPORT_R_EXEC 253 1.2 itohy RELOC(_C_LABEL(_memcp), %a6) 254 1.2 itohy movel %a0,%a6@ 255 1.1 itohy # else 256 1.2 itohy movel %a0,_C_LABEL(_memcp) 257 1.1 itohy # endif 258 1.1 itohy #endif 259 1.1 itohy 260 1.1 itohy | 261 1.1 itohy | save PDB address 262 1.1 itohy | 263 1.1 itohy #if NEED_PROCP 264 1.1 itohy # if SUPPORT_R_EXEC 265 1.2 itohy RELOC(_C_LABEL(_procp), %a6) 266 1.2 itohy movel %a5,%a6@ 267 1.1 itohy # else 268 1.2 itohy movel %a5,_C_LABEL(_procp) 269 1.1 itohy # endif 270 1.1 itohy #endif 271 1.1 itohy 272 1.1 itohy | 273 1.1 itohy | get version no of Human 274 1.1 itohy | 275 1.1 itohy #if NEED_VERNUM 276 1.1 itohy DOS(__VERNUM) 277 1.1 itohy # if SUPPORT_R_EXEC 278 1.2 itohy RELOC(_C_LABEL(_vernum), %a6) 279 1.2 itohy movel %d0,%a6@ 280 1.1 itohy # else 281 1.2 itohy movel %d0,_C_LABEL(_vernum) 282 1.1 itohy # endif 283 1.1 itohy #endif 284 1.1 itohy 285 1.1 itohy | 286 1.1 itohy | create argv[0] 287 1.1 itohy | 288 1.2 itohy moveal %a1,%a0 | top of argument strings 289 1.1 itohy #if SUPPORT_HUPAIR && HUPAIR_ARGV0 290 1.2 itohy tstb %d3 291 1.1 itohy beqs arg0lp 292 1.1 itohy #endif 293 1.1 itohy #if ADD_PATHNAME 294 1.2 itohy lea %a5@(drvpath_pdb),%a4 | drive and path name 295 1.1 itohy arg0path: 296 1.2 itohy moveb %a4@+,%a1@+ 297 1.1 itohy bnes arg0path 298 1.2 itohy subql #1,%a1 | remove nul char 299 1.1 itohy #endif 300 1.2 itohy lea %a5@(command_pdb),%a4 | command name 301 1.2 itohy arg0lp: moveb %a4@+,%a1@+ 302 1.1 itohy bnes arg0lp 303 1.1 itohy 304 1.1 itohy #if NEED_PROGNAME 305 1.1 itohy | 306 1.1 itohy | find program basename 307 1.1 itohy | 308 1.2 itohy moveal %a1,%a4 309 1.1 itohy prognlp: 310 1.2 itohy cmpal %a0,%a4 311 1.1 itohy beqs prognexit 312 1.2 itohy moveb %a4@-,%d0 313 1.2 itohy cmpib #char_slash,%d0 314 1.1 itohy beqs prognfou 315 1.2 itohy cmpib #char_backslash,%d0 316 1.1 itohy bnes prognlp 317 1.1 itohy prognfou: 318 1.2 itohy addql #1,%a4 | next of slash 319 1.1 itohy prognexit: 320 1.1 itohy # if SUPPORT_R_EXEC 321 1.2 itohy RELOC(_C_LABEL(__progname), %a6) 322 1.2 itohy movel %a4,%a6@ 323 1.1 itohy # else 324 1.2 itohy movel %a4,_C_LABEL(__progname) 325 1.1 itohy # endif 326 1.1 itohy #endif 327 1.1 itohy 328 1.1 itohy | 329 1.1 itohy | create argument strings 330 1.1 itohy | 331 1.2 itohy moveql #1,%d0 | (d0:l) # arg 332 1.1 itohy 333 1.2 itohy spskip: moveb %a2@+,%d2 334 1.1 itohy beqs comline_end 335 1.2 itohy cmpb %d4,%d2 | space 336 1.1 itohy beqs spskip 337 1.2 itohy cmpb %d3,%d2 | tab (if not hupair) 338 1.1 itohy beqs spskip 339 1.1 itohy 340 1.1 itohy | create an arg 341 1.2 itohy clrb %d1 | no quote here 342 1.2 itohy addql #1,%d0 | increment argc 343 1.1 itohy 344 1.2 itohy arglp: tstb %d1 345 1.1 itohy bnes in_quote 346 1.2 itohy cmpib #char_dquote,%d2 347 1.1 itohy beqs quote 348 1.2 itohy cmpib #char_squote,%d2 349 1.1 itohy bnes notquote 350 1.2 itohy quote: moveb %d2,%d1 | save quote character 351 1.1 itohy bras argnextc 352 1.1 itohy 353 1.1 itohy in_quote: 354 1.2 itohy cmpb %d1,%d2 355 1.1 itohy bnes argcopyc 356 1.2 itohy clrb %d1 | quote ended 357 1.1 itohy bras argnextc 358 1.1 itohy 359 1.1 itohy notquote: 360 1.2 itohy cmpb %d4,%d2 | space 361 1.1 itohy beqs arg_end 362 1.2 itohy cmpb %d3,%d2 | tab (if not hupair) 363 1.1 itohy bnes argcopyc 364 1.1 itohy arg_end: 365 1.2 itohy clrb %a1@+ 366 1.1 itohy bras spskip 367 1.1 itohy 368 1.1 itohy argcopyc: 369 1.2 itohy moveb %d2,%a1@+ | copy char 370 1.1 itohy 371 1.1 itohy argnextc: 372 1.2 itohy moveb %a2@+,%d2 373 1.1 itohy bnes arglp 374 1.2 itohy clrb %a1@+ 375 1.1 itohy 376 1.1 itohy comline_end: 377 1.1 itohy 378 1.1 itohy | 379 1.1 itohy | create argv vector 380 1.1 itohy | 381 1.2 itohy addql #3,%a1 382 1.2 itohy movel %a1,%d1 383 1.2 itohy andib #0xfc,%d1 | long alignment 384 1.2 itohy moveal %d1,%a1 | argv 385 1.2 itohy movel %d0,%d4 | argc 386 1.1 itohy | a0 is at argument strings 387 1.1 itohy mkargv: 388 1.2 itohy movel %a0,%a1@+ | argv[0] ... 389 1.2 itohy nxtarg: tstb %a0@+ 390 1.1 itohy bnes nxtarg 391 1.1 itohy #if STRICT_SETBLOCK 392 1.2 itohy subqw #1,%d0 393 1.1 itohy #else 394 1.2 itohy subqw #1,%d4 395 1.1 itohy #endif 396 1.1 itohy bnes mkargv 397 1.1 itohy 398 1.2 itohy clrl %a1@+ | argv[argc] should be NULL 399 1.1 itohy 400 1.1 itohy | 401 1.1 itohy | create envp vector 402 1.1 itohy | 403 1.1 itohy #if NEED_ENVIRON 404 1.2 itohy movel %a1,%d2 405 1.2 itohy envlp: tstb %a3@ 406 1.1 itohy beqs envend 407 1.2 itohy movel %a3,%a1@+ 408 1.2 itohy envskp: tstb %a3@+ 409 1.1 itohy bnes envskp 410 1.1 itohy bras envlp 411 1.2 itohy envend: clrl %a1@+ | NULL termination 412 1.1 itohy # if SUPPORT_R_EXEC 413 1.2 itohy RELOC(_C_LABEL(environ), %a0) 414 1.2 itohy movel %d2,%a0@ 415 1.1 itohy # else 416 1.2 itohy movel %d2,_C_LABEL(environ) 417 1.1 itohy # endif 418 1.1 itohy #endif 419 1.1 itohy 420 1.1 itohy | 421 1.1 itohy | free unused memory 422 1.1 itohy | 423 1.1 itohy #if STRICT_SETBLOCK 424 1.2 itohy subal %a5,%a1 425 1.2 itohy movel %a1,%a7@- 426 1.2 itohy movel %a5,%a7@- 427 1.1 itohy DOS(__SETBLOCK) | reset donburi-kanjo (never fails) 428 1.2 itohy addql #8,%a7 429 1.2 itohy movel %d4,%d0 | argc 430 1.1 itohy #endif 431 1.1 itohy 432 1.1 itohy | 433 1.1 itohy | make parameter 434 1.1 itohy | 435 1.1 itohy #if NEED_ENVIRON 436 1.2 itohy movel %d2,%a7@- | arg #3 --- envp 437 1.1 itohy #endif 438 1.1 itohy #if !C_REGPARM 439 1.2 itohy movel %d1,%a7@- | arg #2 --- argv 440 1.2 itohy movel %d0,%a7@- | arg #1 --- argc 441 1.1 itohy #endif 442 1.1 itohy 443 1.1 itohy #if SUPPORT_R_EXEC 444 1.2 itohy RELOC(_C_LABEL(main), %a0) 445 1.2 itohy jsr %a0@ 446 1.1 itohy #else 447 1.2 itohy jsr _C_LABEL(main) 448 1.1 itohy #endif 449 1.1 itohy 450 1.1 itohy #if !C_REGPARM || NEED_ENVIRON 451 1.2 itohy movew %d0,%a7@ 452 1.1 itohy #else 453 1.2 itohy movew %d0,%a7@- 454 1.1 itohy #endif 455 1.1 itohy DOS(__EXIT2) 456 1.1 itohy 457 1.2 itohy #if !defined(__ELF__) && DUMMY___main 458 1.2 itohy ENTRY_NOPROFILE(__main) 459 1.1 itohy rts 460 1.1 itohy #endif 461 1.1 itohy 462 1.1 itohy |----------------------------------------------------------- 463 1.1 itohy | 464 1.1 itohy | variables 465 1.1 itohy | 466 1.1 itohy #if NEED_MEMCP 467 1.2 itohy .comm _C_LABEL(_memcp),4 468 1.1 itohy #endif 469 1.1 itohy 470 1.1 itohy #if NEED_PROCP 471 1.2 itohy .comm _C_LABEL(_procp),4 | PDB address 472 1.1 itohy #endif 473 1.1 itohy 474 1.1 itohy #if NEED_VERNUM 475 1.2 itohy .comm _C_LABEL(_vernum),4 476 1.1 itohy #endif 477 1.1 itohy 478 1.1 itohy #if NEED_PROGNAME 479 1.2 itohy .comm _C_LABEL(__progname),4 480 1.1 itohy #endif 481 1.1 itohy 482 1.1 itohy #if NEED_ENVIRON 483 1.2 itohy .comm _C_LABEL(environ),4 | environ address 484 1.1 itohy #endif 485 1.1 itohy 486 1.1 itohy |----------------------------------------------------------- 487 1.1 itohy | 488 1.1 itohy | stack 489 1.1 itohy | 490 1.2 itohy #ifdef __ELF__ 491 1.2 itohy .section .stack,"aw",@nobits 492 1.2 itohy .align 4 493 1.2 itohy STACK_SYMBOL: 494 1.2 itohy .space STACK_SIZE 495 1.2 itohy #else 496 1.1 itohy .comm STACK_SYMBOL,STACK_SIZE 497 1.2 itohy #endif 498