
;	cdos.p86 - c ultra main program
;
;	 6 Nov 1989	bug fix - setting up 80x87
;	14 Dec 1989	bug fix - delete .286p directive
;	 5 Mar 1990	add _PROFILER for profiler
;	15 Jun 1990	change profiler code


SIGINT		EQU	2	;   these value must be the same
SIGFPE		EQU	8	; as ones in signal.h
FPE_INTDIV0	EQU	1	;   from float.h

#if	_P_FAR
	#define	RETX	RETF
	#define	CALLX	CALLF
	#define	JMPX	JMPF
#else
	#define	RETX	RET
	#define	CALLX	CALL
	#define	JMPX	JMP
#endif

#if	_D_FAR

CGROUP	GROUP	TEXT

FAR_DATA	DSEG	'FAR_DATA'

DGROUP	GROUP	BEGIN,DATA,COUNT,BSS,ENDBSS,XSTACK,ENDSTK

TEXT	CSEG
BEGINTEXT:
	MOV	AX,DGROUP
	MOV	ES,AX

	;adjust stack
	MOV	SS,AX
	MOV	SP,_ENDSTACK

	MOV	ES:[_pid_],DS

	MOV	AH,30H	;VERSION #
	INT	21H
	MOV	ES:[_osmajor_],AX

	MOV	BL,[80H]
	XOR	BH,BH
	MOV	[81H+BX].B,0

	PUSH	DS
	PUSH	ES

	MOV	DS,[2CH]
	MOV	ES:[_environ_+2],DS

	;skip environment variables
	CLD
	XOR	SI,SI
	_1:	LODSB
		TEST	AL,AL
		JE	_2
		_3:	LODSB
			TEST	AL,AL
			JNZ	_3
		JMP	_1
	_2:

	;check if argv[0] exists
	CMP	ES:[_osmajor_].B,3
	JB	_4
	CMP	[SI].W,1
	JB	_4
		INC	SI
		INC	SI
		MOV	ES:[_argv0_],SI
		MOV	ES:[_argv0_+2],DS
	_4:

	;clear BSS
	CLD
	MOV	DI,BEGINBSS
	MOV	CX,SP		; BSS and STACK
	SUB	CX,DI
	SHR	CX,1
	XOR	AX,AX
	REP STOSW

	;clear FAR_BSS
	MOV	BX,FAR_BSS
	XOR	AX,AX
	_10:	MOV	AX,HEAP
		SUB	AX,BX
		JBE	_20
		MOV	CX,AX
		SHL	CX,3
		CMP	AX,1000H
		JBE	_15
			MOV	AX,1000H
			MOV	CX,8000H
		_15:
		MOV	ES,BX
		ADD	BX,AX
		XOR	DI,DI
		XOR	AX,AX
		REP STOSW
		JMP	_10
	_20:
	POP	DS	;DS = default Data Segment
	POP	ES	;ES = PSP

	;set initial memory size
	MOV	BX,HEAP
	MOV	AX,ES
	SUB	BX,AX
	MOV	AH,4AH
	INT	21H
	JC	ABORT

;check if 8087 exists
	FNINIT
	MOV	[_8087_].W,5A5AH
	FNSTSW	[_8087_]
	CMP	[_8087_].B,0
	JNE	_80

	FNSTCW	[_8087_]
	MOV	AX,[_8087_]
	AND	AX,103FH
	CMP	AX,3FH
	JNE	_80
		FLDCW	[__cw87].W
		MOV	[_8087_].W,1	; with 80x87
		FWAIT
		JMP	_90
	_80:
		MOV	[_8087_].W,0	; without 8087
	_90:

	PUSH	ES

	CALL	_setMyHandler
	CALLX	_calcSum_##

;go to ultra main program
	POP	BX
	MOV	AX,81H
	JMPX	_main_##


_setMyHandler:
;set my interrupt handler
	MOV	AX,02523h	; set INT 23H
	PUSH	DS
	PUSH	CS
	POP	DS
	MOV	DX,_INTBRK_
	INT	21h
	POP	DS

	MOV	AX,02524h	; set INT 24H
	PUSH	DS
	PUSH	CS
	POP	DS
	MOV	DX,_HARDERR_
	INT	21h
	POP	DS

	MOV	AX,03500h	; get original INTDIV
	INT	21h
	MOV	0[_INTDIV_save],BX
	MOV	2[_INTDIV_save],ES
	MOV	AX,02500h	; set INTDIV
	PUSH	DS
	PUSH	CS
	POP	DS
	MOV	DX,_INTDIV_
	INT	21h
	POP	DS
	RET


_resetMyHandler::
;reset my interrupt handler
	PUSH	DS
	PUSH	DX
	LDS	DX,[_INTDIV_save]
	MOV	AX,DS
	OR	AX,DX
	JZ	RMH_100
		MOV	AX,2500h	; restore original INTDIV
		INT	21h
	RMH_100:
	POP	DX
	POP	DS
	RETX



_INTDIV_::
	PUSH	AX
	PUSH	DS
	MOV	AX,DGROUP
	MOV	DS,AX
	CMP	[_child].b,0
	JZ	_INTDIV_1
		PUSH	2[_INTDIV_save].w
		PUSH	0[_INTDIV_save].w
		PUSH	BP
		MOV	BP,SP
		MOV	AX,[BP+8]
		MOV	DS,[BP+6]
		POP	BP
		RETF	4
_INTDIV_1:
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	ES
	PUSH	SI
	PUSH	DI
	PUSH	BP
	MOV	AX,SIGFPE
	MOV	BX,FPE_INTDIV0
	STI
	CALLX	[_div0_handler_]
	POP	BP
	POP	DI
	POP	SI
	POP	ES
	POP	DX
	POP	CX
	POP	BX
	POP	DS
	POP	AX
	IRET


_INTBRK_:
	PUSH	AX
	PUSH	DS
	MOV	AX,DGROUP
	MOV	DS,AX
	CMP	[_child].b,0
	JZ	_INTBRK_1
		MOV	DS,[_pid_]
		PUSH	2[0EH].w
		PUSH	0[0EH].w
		PUSH	BP
		MOV	BP,SP
		MOV	AX,[BP+8]
		MOV	DS,[BP+6]
		POP	BP
		RETF	4
_INTBRK_1:
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	ES
	PUSH	SI
	PUSH	DI
	PUSH	BP
	MOV	AX,SIGINT
	XOR	BX,BX
	STI
	CALLX	[_brk_handler_]
	POP	BP
	POP	DI
	POP	SI
	POP	ES
	POP	DX
	POP	CX
	POP	BX
	POP	DS
	POP	AX
	IRET


save_ret:	rs	6

_HARDERR_:
	PUSH	AX
	PUSH	DS
	MOV	AX,DGROUP
	MOV	DS,AX
	CMP	[_child].b,0
	JZ	_HARDERR_1
		MOV	DS,[_pid_]	; chain to pre-installed handler
		PUSH	2[12H].w	; INT 24H handler in PSP
		PUSH	0[12H].w
		PUSH	BP
		MOV	BP,SP
		MOV	AX,[BP+8]
		MOV	DS,[BP+6]
		POP	BP
		RETF	4
	_HARDERR_1:
		PUSH	2[_harderr_handler_].w
		PUSH	0[_harderr_handler_].w
		PUSH	BP
		MOV	BP,SP
		MOV	AX,10[BP]
		MOV	0[save_ret],AX
		MOV	AX,12[BP]
		MOV	2[save_ret],AX
		MOV	AX,14[BP]
		MOV	4[save_ret],AX
		MOV	AX,CS
		MOV	12[BP],CS
		MOV	AX,_HARDERR_END
		MOV	10[BP],AX
		MOV	AX,[BP+8]
		MOV	DS,[BP+6]
		POP	BP
		RETF	4

_DEF_HARDERR_::
	PUSH	AX
	PUSH	DS
	MOV	AX,DGROUP
	MOV	DS,AX
	MOV	DS,[_pid_]	; chain to pre-installed handler
	PUSH	2[12H].w	; INT 24H handler in PSP
	PUSH	0[12H].w
	PUSH	BP
	MOV	BP,SP
	MOV	AX,[BP+8]
	MOV	DS,[BP+6]
	POP	BP
	RETF	4

_HARDERR_END:
	CMP	AL,2
	JNZ	_HARDERR_END_10
		PUSH	AX
		PUSH	DS
		MOV	AX,DGROUP
		MOV	DS,AX
		CALLX	_resetMyHandler
		POP	DS
		POP	AX
_HARDERR_END_10:
	PUSH	4[save_ret].w
	PUSH	2[save_ret].w
	PUSH	0[save_ret].w
	IRET



_DEF_DIV0_::
	MOV	AX,_ERR_DIV0
	MOV	BX,seg _ERR_DIV0
	CALLX	_puterrmes_##
_DEF_BRK_::
	MOV	AX,1
;	JMPX	_exit_

_exit_::
	PUSH	AX	; save retrun code

#if	_PROFILER
;save counter vector
	XOR	CX,CX
	MOV	DX,proffilename
	MOV	AH,3CH	;create
	INT	21H
	JC	OPENERR

	MOV	BX,AX	;handle
	MOV	SI,vector.org
	_PRO10:	CMP	SI,BEGINBSS-6
		JA	_PRO20
		PUSH	DS
		MOV	CX,[SI]		;# of bytes to be written
		LDS	DX,[SI+2]	;Address of counters
		MOV	AH,40H	;write
		INT	21H
		ADD	SI,6
		POP	DS
		JMP	_PRO10
	_PRO20:
	MOV	AH,3EH	;close
	INT	21H
OPENERR:
#endif
	CALLX	_nullcheck_##
	PUSH	AX
	CALLX	_resetMyHandler
	POP	AX
	TEST	AX,AX
	POP	AX	; return code
	JZ	_120
ABORT:
		MOV	AL,1
	_120:
	MOV	AH,4Ch
	INT	21h	; return to parent process

sbrk_::
	MOV	BX,AX
	INC	BX
	JZ	_sbrk1
	AND	BX,-2	; word align
	MOV	AX,BX
	CMP	[LASTALLOCSEG].W,0
	JE	_sbrk1
	MOV	BX,AX
	ADD	BX,[LASTALLOCOFF]
	JC	_sbrk1
	;try to extend last allocated block
		ADD	BX,16-1
		RCR	BX,1
		SHR	BX,3
		PUSH	AX
		MOV	AH,4AH
		MOV	ES,[LASTALLOCSEG]
		INT	21H
		POP	AX
		JC	_sbrk1
		ADD	AX,[LASTALLOCOFF]
		XCHG	AX,[LASTALLOCOFF]
		MOV	BX,ES
		RETX
	_sbrk1:
	;fail; allocate new segment

	PUSH	AX
	ADD	AX,16-1
	RCR	AX,1
	SHR	AX,3
	MOV	BX,AX
	MOV	AH,48H
	INT	21H
	POP	BX
	JC	brk_
	MOV	[LASTALLOCSEG],AX
	MOV	[LASTALLOCOFF],BX
	MOV	BX,AX
	XOR	AX,AX
	RETX
brk_::
	MOV	AX,-1
	MOV	BX,-1
	RETX



BEGIN		DSEG	PARA

DATA		DSEG
		DB	0,0,0,0,'LSI C-86 Run-Time Library'
_ERR_DIV0:	DB	13,10,'Division by 0',0
_osmajor_::	DB	0
_osminor_::	DB	0
_child::	DB	0
	EVEN
LASTALLOCOFF:	DW	0
LASTALLOCSEG:	DW	0

_environ_::	DW	0,0
_argv0_::	DW	0,0
_8087_::	DW	0
_st87::		DW	0
_cw87::		DW	1332h
__cw87::	DW	133Fh
_psp_::
_pid_::		DW	0
_INTDIV_save:	DW	0,0
#if	_P_FAR
_brk_handler_::		DW	_DEF_BRK_
			DW	seg _DEF_BRK_
_div0_handler_::	DW	_DEF_DIV0_
			DW	seg _DEF_DIV0_
#else
_brk_handler_::		DW	_DEF_BRK_
_div0_handler_::	DW	_DEF_DIV0_
#endif
_harderr_handler_::	DW	_DEF_HARDERR_, seg _DEF_HARDERR_


COUNT		DSEG

#if	_PROFILER
proffilename:	db	'prof.out',0
vector.org:
#endif


BSS		DSEG
BEGINBSS:

ENDBSS		DSEG
_STACK::

XSTACK		DSEG	STACK	'STACK'
		RS	5000	;minimum size;  overridden by link option

ENDSTK		DSEG	'STACK'
_ENDSTACK::

FAR_BSS		DSEG	'FAR_BSS' PARA

HEAP		DSEG	'HEAP' PARA

#else
CGROUP	GROUP	TEXT

FAR_DATA	DSEG	'FAR_DATA'
FAR_BSS		DSEG	'FAR_BSS'

DGROUP	GROUP	BEGIN,DATA,COUNT,BSS,ENDBSS,XSTACK,HEAP

TEXT	CSEG
BEGINTEXT:
	MOV	AX,DGROUP

	;adjust stack
	MOV	SS,AX
	MOV	SP,_ENDSTACK

	MOV	SS:[_pid_],DS

	MOV	AH,30H	;VERSION #
	INT	21H
	MOV	SS:[_osmajor_],AX

	; allocate heap for initial data
	MOV	BL,[80H]	; length of command line
	XOR	BH,BH
	INC	BX

	MOV	ES,[2CH]	; length of environment variables
	PUSH	SS
	POP	DS
	XOR	DI,DI
	MOV	CX,0FFFFH
	XOR	AL,AL
	CLD
	JMP	_1
	_2:
		REPNE SCASB
		JNZ	NOMEM
	_1:
		DEC	CX
		SCASB
		JNZ	_2
	MOV	DX,CX
	NOT	DX

	XOR	CX,CX		; length of argv[0]
	CMP	[_osmajor_].B,3
	JB	_3
	CMP	ES:[DI].W,1
	JB	_3
		INC	DI
		INC	DI
		MOV	CX,0FFFFH
		REPNE SCASB
		JNZ	NOMEM
		NOT	CX
	_3:

	MOV	AX,HEAPTOP
	ADD	AX,BX
	ADD	AX,CX
	ADD	AX,DX
	INC	AX
	AND	AX,-2	; word align
	CALLX	brk_
	INC	AX
	JZ	NOMEM

	;copy command line to local data segment
	MOV	BX,CX
	PUSH	SS
	POP	ES
	MOV	DS,[_pid_]
	MOV	CL,[80H]
	XOR	CH,CH
	MOV	SI,81H
	MOV	DI,HEAPTOP
	REP MOVSB
	MOV	ES:[DI].B,0
	INC	DI

	;copy environment variables to local data segment
	MOV	ES:[_environ_],DI
	MOV	DS,[2CH]
	XOR	SI,SI
	MOV	CX,DX
	REP MOVSB

	;copy argv[0] to local data segment
	TEST	BX,BX
	JZ	_4
		INC	SI
		INC	SI
		MOV	ES:[_argv0_],DI
		MOV	CX,BX
		REP MOVSB
	_4:

	PUSH	ES
	POP	DS

	;clear BSS
	CLD
	MOV	DI,BEGINBSS
	MOV	CX,SP		; BSS and STACK
	SUB	CX,DI
	SHR	CX,1
	XOR	AX,AX
	REP STOSW

;check if 80x87 exists
	FNINIT
	MOV	[_8087_].W,5A5AH
	FNSTSW	[_8087_]
	CMP	[_8087_].B,0
	JNE	_80

	FNSTCW	[_8087_]
	MOV	AX,[_8087_]
	AND	AX,103FH
	CMP	AX,3FH
	JNE	_80
		FLDCW	[__cw87].W
		MOV	[_8087_].W,1	; with 80x87
		FWAIT
		JMP	_90
	_80:
		MOV	[_8087_].W,0	; without 80x87
	_90:

	CALL	_setMyHandler
	CALLX	_calcSum_##

;go to ultra main program
	MOV	AX,HEAPTOP
	JMPX	_main_##


NOMEM:
	MOV	AX,NOMEM_MSG
	CALLX	_puterrmes_##
	JMP	ABORT


_setMyHandler:
;set my interrupt handler
	MOV	AX,02523h	; set INT 23H
	PUSH	DS
	PUSH	CS
	POP	DS
	MOV	DX,_INTBRK_
	INT	21h
	POP	DS

	MOV	AX,02524h	; set INT 24H
	PUSH	DS
	PUSH	CS
	POP	DS
	MOV	DX,_HARDERR_
	INT	21h
	POP	DS

	PUSH	ES
	MOV	AX,03500h	; get original INTDIV
	INT	21h
	MOV	0[_INTDIV_save],BX
	MOV	2[_INTDIV_save],ES
	MOV	AX,02500h	; set INTDIV
	PUSH	DS
	PUSH	CS
	POP	DS
	MOV	DX,_INTDIV_
	INT	21h
	POP	DS
	POP	ES
	RET


_resetMyHandler::
;reset my interrupt handler
	PUSH	DS
	PUSH	DX
	LDS	DX,[_INTDIV_save]
	MOV	AX,DS
	OR	AX,DX
	JZ	RMH_100
		MOV	AX,2500h	; restore original INTDIV
		INT	21h
	RMH_100:
	POP	DX
	POP	DS
	RETX



_INTDIV_::
	PUSH	AX
	PUSH	DS
	MOV	AX,DGROUP
	MOV	DS,AX
	CMP	[_child].b,0
	JZ	_INTDIV_1
		PUSH	2[_INTDIV_save].w
		PUSH	0[_INTDIV_save].w
		PUSH	BP
		MOV	BP,SP
		MOV	AX,[BP+8]
		MOV	DS,[BP+6]
		POP	BP
		RETF	4
_INTDIV_1:
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	ES
	PUSH	SI
	PUSH	DI
	PUSH	BP
	MOV	AX,SIGFPE
	MOV	BX,FPE_INTDIV0
	STI
	CALLX	[_div0_handler_]
	POP	BP
	POP	DI
	POP	SI
	POP	ES
	POP	DX
	POP	CX
	POP	BX
	POP	DS
	POP	AX
	IRET


_INTBRK_:
	PUSH	AX
	PUSH	DS
	MOV	AX,DGROUP
	MOV	DS,AX
	CMP	[_child].b,0
	JZ	_INTBRK_1
		MOV	DS,[_pid_]
		PUSH	2[0EH].w
		PUSH	0[0EH].w
		PUSH	BP
		MOV	BP,SP
		MOV	AX,[BP+8]
		MOV	DS,[BP+6]
		POP	BP
		RETF	4
_INTBRK_1:
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	ES
	PUSH	SI
	PUSH	DI
	PUSH	BP
	MOV	AX,SIGINT
	XOR	BX,BX
	STI
	CALLX	[_brk_handler_]
	POP	BP
	POP	DI
	POP	SI
	POP	ES
	POP	DX
	POP	CX
	POP	BX
	POP	DS
	POP	AX
	IRET


save_ret:	rs	6

_HARDERR_:
	PUSH	AX
	PUSH	DS
	MOV	AX,DGROUP
	MOV	DS,AX
	CMP	[_child].b,0
	JZ	_HARDERR_1
		MOV	DS,[_pid_]	; chain to pre-installed handler
		PUSH	2[12H].w	; INT 24H handler in PSP
		PUSH	0[12H].w
		PUSH	BP
		MOV	BP,SP
		MOV	AX,[BP+8]
		MOV	DS,[BP+6]
		POP	BP
		RETF	4
	_HARDERR_1:
		PUSH	2[_harderr_handler_].w
		PUSH	0[_harderr_handler_].w
		PUSH	BP
		MOV	BP,SP
		MOV	AX,10[BP]
		MOV	0[save_ret],AX
		MOV	AX,12[BP]
		MOV	2[save_ret],AX
		MOV	AX,14[BP]
		MOV	4[save_ret],AX
		MOV	AX,CS
		MOV	12[BP],CS
		MOV	AX,_HARDERR_END
		MOV	10[BP],AX
		MOV	AX,[BP+8]
		MOV	DS,[BP+6]
		POP	BP
		RETF	4

_DEF_HARDERR_::
	PUSH	AX
	PUSH	DS
	MOV	AX,DGROUP
	MOV	DS,AX
	MOV	DS,[_pid_]	; chain to pre-installed handler
	PUSH	2[12H].w	; INT 24H handler in PSP
	PUSH	0[12H].w
	PUSH	BP
	MOV	BP,SP
	MOV	AX,[BP+8]
	MOV	DS,[BP+6]
	POP	BP
	RETF	4

_HARDERR_END:
	CMP	AL,2
	JNZ	_HARDERR_END_10
		PUSH	AX
		PUSH	DS
		MOV	AX,DGROUP
		MOV	DS,AX
		CALLX	_resetMyHandler
		POP	DS
		POP	AX
_HARDERR_END_10:
	PUSH	4[save_ret].w
	PUSH	2[save_ret].w
	PUSH	0[save_ret].w
	IRET



_DEF_DIV0_::
	MOV	AX,_ERR_DIV0
	CALLX	_puterrmes_##
_DEF_BRK_::
	MOV	AX,1
;	JMP	_exit_

_exit_::
	PUSH	AX	; save retrun code

#if	_PROFILER
;save counter vector
	XOR	CX,CX
	MOV	DX,proffilename
	MOV	AH,3CH	;create
	INT	21H
	JC	OPENERR

	MOV	BX,AX	;handle
	MOV	SI,vector.org
	_PRO10:	CMP	SI,BEGINBSS-6
		JA	_PRO20
		PUSH	DS
		MOV	CX,[SI]		;# of bytes to be written
		LDS	DX,[SI+2]	;Address of counters
		MOV	AH,40H	;write
		INT	21H
		ADD	SI,6
		POP	DS
		JMP	_PRO10
	_PRO20:
	MOV	AH,3EH	;close
	INT	21H
OPENERR:
#endif
	CALLX	_nullcheck_##
	PUSH	AX
	CALLX	_resetMyHandler
	POP	AX
	TEST	AX,AX
	POP	AX	; return code
	JZ	_120
ABORT:
		MOV	AL,1
	_120:
	MOV	AH,4Ch
	INT	21h	; return to parent process


;void	*sbrk(size_t size);
;void	*brk(void *top);

sbrk_::
	INC	AX
	JZ	_99
	AND	AX,-2	; word align
	ADD	AX,[_MEMTOP]
	JB	_99
brk_::
	PUSH	CX
	PUSH	DX
	MOV	BX,AX
	MOV	CL,4
	SHR	BX,CL
	INC	BX
	MOV	CX,DS
	MOV	DX,CS
	SUB	DX,10H
	SUB	CX,DX
	ADD	BX,CX
	POP	DX
	POP	CX
	CMP	BX,[_BLKTOP]
	JBE	_10
	;requires memory allocation
		PUSH	AX
		PUSH	ES
		MOV	AX,CS
		SUB	AX,10H
		MOV	ES,AX
		MOV	AH,4AH	;set block function
		INT	21H
		POP	ES
		POP	AX
		JB	_99
		MOV	[_BLKTOP],BX
	_10:
	XCHG	AX,[_MEMTOP]
	RETX
_99:
	MOV	AX,-1
	RETX


;void	_rsv64k(void);

_rsv64k_::
	PUSH	[_MEMTOP]
	MOV	AX,0FFFFH
	CALLX	brk_
	POP	[_MEMTOP]
	RETX



BEGIN		DSEG	PARA

DATA		DSEG
		DB	0,0,0,0,'LSI C-86 Run-Time Library'
_ERR_DIV0:	DB	13,10,'Division by 0',13,10,0
NOMEM_MSG:	DB	13,10,'not enough memory',13,10,0
_osmajor_::	DB	0
_osminor_::	DB	0
_child::	DB	0
	EVEN
_MEMTOP:	DW	0
_blktop_::
_BLKTOP:	DW	0
_environ_::	DW	0
_argv0_::	DW	0
_8087_::	DW	0
_st87::		DW	0
_cw87::		DW	1332h
__cw87::	DW	133Fh
_psp_::
_pid_::		DW	0
_INTDIV_save:	DW	0,0
#if	_P_FAR
_brk_handler_::		DW	_DEF_BRK_
			DW	seg _DEF_BRK_
_div0_handler_::	DW	_DEF_DIV0_
			DW	seg _DEF_DIV0_
#else
_brk_handler_::		DW	_DEF_BRK_
_div0_handler_::	DW	_DEF_DIV0_
#endif
_harderr_handler_::	DW	_DEF_HARDERR_, seg _DEF_HARDERR_


COUNT		DSEG

#if	_PROFILER
proffilename:	db	'prof.out',0
vector.org:
#endif


BSS		DSEG
BEGINBSS:

ENDBSS		DSEG
_STACK::

XSTACK		DSEG	STACK	'STACK'
		RS	2500	; minimum size;  overridden by link option

HEAP		DSEG	'HEAP'
_ENDSTACK::
HEAPTOP:
#endif
	END	BEGINTEXT
