*************************************************************************
*	C-RunTime Routine 3						*
*	コマンドライン分割読み取りなし					*
*	（コマンドラインからのスタック＆ヒープサイズ変更不可）		*
*	自分の環境＝親の環境						*
*	putenv()使用不可（内部でそれを使う関数もダメ）			*
*	グローバル変数environ変更					*
*	srand()での初期化なし（ユーザーが行なう）			*
*	tzset()の初期化なし（ユーザーが行なう）				*
*	clock()の初期化なし（ユーザーがclock_init()で行なう）		*
*	一部外部シンボル削除（PSTA/PEND/DSTA/DEND/BSTA/BEND/SSTA/SEND）	*
*	main(unchar *cmdline)						*
*************************************************************************
* Copyright 1992 SHARP/Hudson	(1992/03/03)
* Arranged 1993,96 AIG-SOFT
* 1993/08/17 malloc() -> newmalloc()
* 1996/01/14 Human68K v3.x対応

_STACK_MIN	equ	4096		* スタックサイズ（必ず偶数のこと）
_HEAP_MIN	equ	8*1024		* 最小ヒープサイズ（必ず偶数のこと）
LIB_STACK	equ	1024		* ライブラリ用スタックエリアサイズ（必ず偶数のこと）

	* 外部宣言シンボル
	xdef	__main			* startup main
	xdef	__stack_over
	xdef	__fmode
	xdef	__liobuf
	xdef	__cmdline
	xdef	_environ
	xdef	__PSP
	xdef	__HSTA
	xdef	__HDEF
	xdef	__HEND
	xdef	MALLOCP
	xdef	_errno
	xdef	__doserrno
	xdef	__iob
	xdef	__pback
	* 外部参照シンボル
	xref	_STACK_SIZE
	xref	_HEAP_SIZE
	xref	_main			* user's main
	xref	_newmalloc
	xref	__getiob		* for standard iob set
	xref	_exit
	xref	__exit
	xref	_flushall
	xref	DOSINIT

	include	doscall.mac
	include	stdio.mac
	include	fcntl.mac

	comm	_errno,4
	comm	__doserrno,4
	comm	__iob,(SIZE_IOBUF*__NFILE)
	comm	__pback,2

*000000	mem pointer(16)
*000010	PSP	__PSP
*000100	-----	__PSTA
*	.text(program)
*	     (lib program & data)
*	-----	__PEND
*??????	-----	__DSTA
*	.data(data)
*	-----	__DEND
*??????	-----	__BSTA
*	.bss(C text bss)
*	-----	__BEND
*	.stack(clib bss)
*	ds.b	LIB_STACKバイト（スタックの余裕）
*??????	-----	__SSTA
*	ds.b	_STACK_SIZE(stack & auto)
*	-----	__SEND
*??????	-----	__HSTA
*	ds.b	_HEAP_SIZE
*??????	-----	__HDEF(rbrkでここにもどすことが出来る)
*??????	-----	__HEND(sbrkで変更可能)
*	OS free area
*	child & level 2 mem管理

	.text
	dc.b	'X68000 Cﾗｲﾌﾞﾗﾘ Arranged 1993 AIG-SOFT',0
	.even

__main:
	jsr	DOSINIT			* Human68K v3.x対応
	*
	lea	initstack,sp		* work
	
	addq.w	#1,a2			* コマンドラインの１バイト目はその長さなので外す
	move.l	a2,__cmdline		* コマンド・ライン アドレス セット
	addq.w	#4,a3			* 環境の長さ４バイト分を飛ばす
	move.l	a3,_environ		* 環境アドレス セット
	
	* a1=プログラム終了アドレス(.data,.bssを含む）
	move.l	a1,d1			* その後ろにライブラリ用のスタック領域を取る
	addq.l	#1,d1			*
	and.l	#$fffffe,d1		* .evenと同じ処理
	add.l	#LIB_STACK,d1		* lib stack
	add.l	#_STACK_MIN,d1
	move.l	d1,__SEND		* ライブラリスタック終了アドレス
	
	move.l	d1,__HSTA		* そこからヒープ領域になる
	add.l	#_HEAP_MIN+12,d1
	move.l	d1,__HDEF		* デフォルトのヒープ終了アドレス
	move.l	d1,__HEND		* 取り敢えずそこをヒープ終了アドレスとする
	
	lea	16(a0),a5		* プロセス管理ポインタ
	move.l	a5,__PSP
	sub.l	a5,d1			* 当プログラム・サイズ
	move.l	d1,-(sp)		* 確保する領域サイズ セット
	move.l	a5,-(sp)		* 確保する領域の先頭アドレス セット
	DOS	_SETBLOCK		* 空き領域確保
	addq.w	#8,sp
	tst.l	d0
	bmi	_memerr			* 領域が確保できない時＝エラー

	move.l	__SEND,sp		* スタック設定

*	ヒープ領域の初期化
	move.l	__HSTA,a0
	move.l	a0,MALLOCP		* ヒープ領域先頭がmalloc()確保エリア先頭
	clr.l	(a0)+			* １つ前のメモリ管理ポインタ＝なし
	move.l	a1,(a0)+		* このメモリーを確保したプロセスのメモリ管理ポインタ
	clr.l	(a0)+			* メモリブロックの終了アドレス＋１（今は確保していない）
	move.l	#'HEAP',(a0)		* 次のメモリ管理ポインタ（今はないのダミー）

*	グローバル領域の初期化
	clr.w	__pback
	clr.l	__fmode			. text mode
	lea	__liobuf,a0
	lea	liomod,a1
	moveq.l	#0,d1
lioinit:
	move.l	d1,-(sp)		. 0,d1.w
	DOS	_IOCTRL
	addq.w	#4,sp
	move.b	d1,(a0)+
	move.b	d0,(a0)+
	move.w	(a1)+,(a0)+
	addq.w	#1,d1
	cmp.w	#5,d1
	bne	lioinit

	move.l	#__iob,a0
	move.l	#((__NFILE)*SIZE_IOBUF)-1,d0
_loop:
	clr.b	(a0)+
	dbra	d0,_loop
	
	lea	__iob,a0
	lea	liomod,a1
	moveq.l	#0,d1
fioinit:
	move.l	d1,-(sp)		. 0,d1.w
	DOS	_IOCTRL
	addq.w	#4,sp
	btst.l	#OS_ISDEV,d0
	beq	blkdev
	move.l	#_IOCHARA+_IONBF,d0
	bra	fiook
blkdev:
	move.l	#_IOBDEV,d0
	movem.l	d0-d1/a1,-(sp)
	move.l	a0,-(sp)
	move.l	#_BUFSIZ,-(sp)
	jsr	_newmalloc
	addq.w	#4,sp
	tst.l	d0
	beq	_memerr
	move.l	(sp)+,a0
	move.l	d0,_PTR(a0)
	move.l	d0,_BASE(a0)
	move.l	#_BUFSIZ,_BSIZE(a0)
	movem.l	(sp)+,d0-d1/a1
fiook:
	or.w	(a1)+,d0
	clr.l	_CNT(a0)
	move.l	d0,_FLAG(a0)
	move.b	d1,_FILE(a0)
	lea	SIZE_IOBUF(a0),a0
	addq.w	#1,d1
	cmp.w	#5,d1
	bne	fioinit
	
	* ＣＴＲＬ−Ｃ／アボートベクターの書き換え
	pea	ctrlca
	move.w	#_CTRLVC,-(sp)
	DOS	_INTVCS
	pea	aborta
	move.w	#_ERRJVC,-(sp)
	DOS	_INTVCS
	lea	12(sp),sp
	
	* ユーザーメインルーチン読みだし
	move.l	__cmdline,-(sp)
	jsr	_main
	addq.w	#8,sp
	
	move.l	d0,-(sp)
	jsr	_exit

aborta:
	move.l	#$3fc,d1
	bra.s	ctrl_abort
ctrlca:
	move.l	#$200,d1
ctrl_abort:
	DOS	_GETPDB
	cmp.l	__PSP,d0
	beq	mainex
	move.w	d1,-(sp)
	DOS	_EXIT2
mainex:
	move.l	d1,-(sp)
	jsr	_flushall
	jsr	__exit

* メモリー不足時のエラー終了
__stack_over:
	pea	stkmsg
	bra	errexit
_memerr:
	pea	errmsg
errexit:
	DOS	_PRINT
	addq.w	#4,sp
	move.l	#127,-(sp)
	jsr	__exit

*****************************************
*	コンスタント領域定義		*
*****************************************

liomod:
		dc.w	O_RDONLY+O_TEXT	. con in
		dc.w	O_WRONLY+O_TEXT	. con out
		dc.w	O_RDWR+O_TEXT	. con err
		dc.w	O_RDWR+O_TEXT	. aux
		dc.w	O_WRONLY+O_TEXT	. prn
	.even
errmsg:		dc.b	'メモリー不足',$0D,$0A,0
stkmsg:		dc.b	'スタック不足',$0D,$0A,0

	.stack

*	ストレージ領域定義

	.even
__PSP:		ds.l	1		* プロセス管理ポインタ
__SEND:		ds.l	1		* ライブラリスタック
__HSTA:		ds.l	1		* ヒープ開始アドレス
__HDEF:		ds.l	1		* 初期ヒープポイント
__HEND:		ds.l	1		* ヒープ終了アドレス
MALLOCP:	ds.l	1		* malloc()アドレス
_environ:	ds.l	1		* 親の環境 = 自分の環境
__cmdline:	ds.l	1		* コマンドライン
__liobuf:
*		dc.b	ＯＳのハンドラ
*		dc.b	ＩＯＣＴＲＬデバイス情報
*		dc.w	オープンモード(0でＯＰＥＮされていない)
		ds.l	96
__fmode:	ds.l	1
		ds.l	20

initstack:
	.end	__main
