// This may look like C code, but it is really -*- Asm -*-
/*
 *  smoke16/libc/src16/crt.s - A C-like runtime stub.
 *  $Revision: 1.16 $
 *  Copyright 1997, 2000, Benjamin Sittler
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/* DEBUG_CRT
 *
 * Define this if you want _entry() to check main() for good
 * behavior. It's not really necessary, but it doesn't hurt...
 * and it's helped me find a few stack-trashing problems
 */
/* #define DEBUG_CRT */

	.comm _errno, 2
	.comm _environ, 2
	
	.text
	.align 1
	.global __entry
__entry:
	mov %a2, [_environ]

#ifdef DEBUG_CRT
	// seed the stack and temp. regs, and store %sp and %fp
	push 0xFACE
	mov %sp, [saved_sp]
	mov %fp, [saved_fp]
	mov 0xDEAD, %t0
	mov 0xBEEF, %t1
	mov 0xF00D, %t2
	mov 0xBABE, %t3
	mov 0xCAFE, %t4
	mov 0xD00D, %t5
#endif /* DEBUG_CRT */

	call _main

#ifdef DEBUG_CRT
	// check the stack and temp. regs
	mov [saved_sp], %a1;	cmpl %sp, %a1;	bne yikes0
	mov [saved_fp], %a1;	cmpl %fp, %a1;	bne yikes1
	mov 0xFACE, %a1;	pop %a2;	cmp %a2, %a1;	bne yikes2
	mov 0xDEAD, %a1;	cmpl %t0, %a1;	bne yikes3
	mov 0xBEEF, %a1;	cmpl %t1, %a1;	bne yikes3
	mov 0xF00D, %a1;	cmpl %t2, %a1;	bne yikes3
	mov 0xBABE, %a1;	cmpl %t3, %a1;	bne yikes3
	mov 0xCAFE, %a1;	cmpl %t4, %a1;	bne yikes3
	mov 0xD00D, %a1;	cmpl %t5, %a1;	bne yikes3
#endif /* DEBUG_CRT */

done:	j __exit

#ifdef DEBUG_CRT
yikes0:	mov YIKES0, %a0;	b yikes
yikes1:	mov YIKES1, %a0;	b yikes
yikes2:	mov YIKES2, %a0;	b yikes
yikes3:	mov YIKES3, %a0
yikes:	mov [_stderr], %a1
	call _fputs
	mov 1, %a0
	b done

	.rdata
	// error message strings
YIKES0:	.zstring "_entry: main trashed stack pointer!\n"
YIKES1:	.zstring "_entry: main trashed frame pointer!\n"
YIKES2:	.zstring "_entry: main trashed stack!\n"
YIKES3:	.zstring "_entry: main trashed temporary regs!\n"

	// a place to store copies of %sp and %fp
	.lcomm saved_sp, 2
	.lcomm saved_fp, 2
#endif /* DEBUG_CRT */
