/* C include file -- run-time support for Small-C  */#asm*   SmallC Cross Compiler Run-Time Support.  *   Target 68HC11. *	L. Konneker Feb. 7, 1987 *	Retarget for 6811 and different assembler.*******************************************************	Run-time start off **   for MC68HC11 EVB board** 	Initialize stack* 	For EVB, put stack in high user ram, HEX DFFF downward	ldx	#57343  	hex DFFF	txs	* 	Some would clear all of memory, not necessary on EVB.*	Clear certain things so that start conditions are always same.*	This is defensive programming but may hide bugs.	clra	clrb	jmp	_main*	note main must not return*	Run time routines are not listed in assembler output.	OPT	nol	*******************************************************	Small C v1 comparison support *	All are dyadic except for lneg. *   Reg x used as a temp  cceq:		tsx	cpd 2,x 	beq cctrue 	bra ccfals ccne:		tsx	cpd 2,x  	bne cctrue 	bra ccfals cclt:		tsx	cpd 2,x  	bgt cctrue 	bra ccfals ccle:		tsx	cpd 2,x 	bge cctrue 	bra ccfals ccgt:		tsx	cpd 2,x 	blt cctrue 	bra ccfals ccge:		tsx	cpd 2,x 	ble cctrue 	bra ccfals ccult:		tsx	cpd 2,x 	bhi cctrue 	bra ccfals ccule:		tsx	cpd 2,x 	bhs cctrue 	bra ccfals ccugt:		tsx	cpd 2,x 	blo cctrue 	bra ccfals ccuge:		tsx	cpd 2,x 	bls cctrue 	bra ccfals * boolean negate,  with coercion to boolean cclneg:	cpd #0 	beq cclne1 	ldd #0 	rts cclne1:	ldd #1 	rts * coerce to boolean type ccbool:	bsr	cclneg 	bra	cclneg ******************************************************* true and false returns common to all compare operationscctrue:	ldd #1 	bra		ccret	to common returnccfals:		clra 	clrb 	bra		ccret	to common return******************************************************* relic ???_Xstktop:* Put stack pointer in reg D	 	tsx 	xgdx 	rts	******************************************************* boolean* inclusive or primary and calling environ stacktop ccior:	tsx	oraa	2,x	orab	3,x	bra		ccret * exclusive or primary and calling environ stacktopccxor:	tsx			get copy of stack ptr	eora	2,x	form result 	eorb	3,x	bra 	ccret	 * and primary and calling environ stacktopccand:	tsx	anda	2,x	andb	3,x	bra		ccret	******************************************************* misc* sign extend low byte primary into high byte primaryccsex:	clra	tstb	bpl	*+3	coma	rts	******************************************************* shift * entry : D contains shift count, stack + 2 is operand* exit  : D contains shifted operand, stack is restored** Uses y reg.* No checking for negative shift count.* First, move shift count from d to x and move operand* from stack to d.ccasr:	xgdx	tsy	ldd		2,yccasr1:	cpx		#0	ble		ccret	asra	rorb	dex	bra ccasr1	* leftccasl:	xgdx	tsy	ldd		2,yccasl1:	cpx		#0	ble		ccret	aslb	rola	dex	bra ccasl1	******************************************************* A return routine common to shift and bitwise logical operations* Move ret adr down the stack on top of operand* Assert that on entry to this routine,* the stack ptr is still as it was on entry to the routine that* jumped here.* Must preserve reg D since it has the result.* Uses reg y.ccret:	pulx			capture return address	tsy				set up y as stack top ptr	stx		,y		store ret adr on top of stack	rts	******************************************************* Two's complement negate the primary registerccneg:	coma		one's complement	comb	addd	#1	plus one	rts******************************************************* Mult 16 bit times 16 bit yielding 16 bit.* Overflow is possible, not checked.* Signed and unsigned, same entry point.* * entry : D contains one operand, *			@ stackptr is return adr*			@ stackptr + 2 is operand* exit  : D contains 16 bit operand,*			stackptr is entry stackptr + 4 ( stack is restored*			to as it was before caller pushed operand.)*cctmpd	equ		0cctmpx	equ		2ccrslt	equ		6ccsmul:ccmul:* shuffle stack	tsx	ldx		2,x	pshx			x op		pshb			d op	psha* stack is now*	d op*	x op*	return address*	word for result* do multiply	tsx	ldaa	cctmpx+1,x	lo d times lo x	mul	std		ccrslt,x	ldd		cctmpd+1,x	lo d times hi x	mul	addb	ccrslt,x	add hi byte of partial result 	stab	ccrslt,x	ldaa	cctmpd,x	hi d times lo x	ldab	cctmpx+1,x	mul	addb	ccrslt,x	add hi byte of partial result	stab	ccrslt,x* restore stack, get result in d	pulx	pulx	puly	ret adr	pula	result	pulb	pshy	rts******************************************************* Divide 16 bit times 16 bit yielding 16 bit.* Underflow is possible, not checked.* Signed and unsigned, same entry point. * entry : D contains divisor, *			@ stackptr is return adr*			@ stackptr + 2 is dividend* exit  : D contains 16 bit quotient,*			remainder not returned.*			stackptr is entry stackptr + 4 ( stack is restored*			to as it was before caller pushed operand.)* ccsdiv* Not implemented yet.  * What follows is 6809 code.* To Be Done: convert all labels to start with cc*|	signed divide*|	calling: (left / right)*|		push left*|		ldd right*|		jsr sdiv*|	result in d, arg popped.*|*	left=6*	right=2*	sign=1*	count=0*	return=4*	CARRY=1*.globl sdiv,div,ASSERTFAIL*.globl prabs*sdiv:	leas	-4(s)*	std	right(s)*	bne	nozero*	swi2*	.byte	ASSERTFAIL*nozero:	jsr	prabs*div:	clr	count(s)	| prescale divisor*	inc	count(s)*mscl:	inc	count(s)*	aslb*	rola*	bpl	mscl*	std	right(s)*	ldd	left(s)*	clr	left(s)*	clr	left+1(s)*div1:	subd	right(s)	| check subtract*	bcc	div2*	addd	right(s)*	andcc	#~CARRY*	bra	div3*div2:	orcc	#CARRY*div3:	rol	left+1(s)	| roll in carry*	rol	left(s)*	lsr	right(s)*	ror	right+1(s)*	dec	count(s)*	bne	div1*	ldd	left(s)*	tst	sign(s)		| sign fiddle*	beq	nochg*	nega*	negb*	sbca	#0*nochg:	std	right(s)	| move return addr*	ldd	return(s)*	std	left(s)*	ldd	right(s)*	leas	6(s)*	rts**|	prabs.  converts both args to unsigned, and*|	remembers result sign as sign a eor sign b*|	used only by divide support*|	result d contains right, sign is non-zero*|	if result (from divide) should be negative.*|*|*.globl prabs*	left=8.*	right=4.*	sign=3.*prabs:	clr	sign(s)*	ldd	left(s)*	bge	tryr*	nega*	negb*	sbca	#0*	std	left(s)*	inc	sign(s)*tryr:	ldd	right(s)*	bge	done*	nega*	negb*	sbca	#0*	dec	sign(s)*	std	right(s)*done:	rts******************************************************** Signed modulo. 16 bit modulo 16 bit yielding 16 bit.* Underflow is possible, not checked. * entry : D contains divisor, *			@ stackptr is return adr*			@ stackptr + 2 is dividend* exit  : D contains 16 bit remainder,*			quotient not returned.*			stackptr is entry stackptr + 4 ( stack is restored*			to as it was before caller pushed operand.)* ccsmod* Not implemented yet.* What follows is 6809 code.* To Be Done: convert all labels to start with cc*|	signed mod*|	calling: (left / right)*|		push left*|		ldd right*|		jsr smod*|	result in d, arg popped.*|*	left=6*	right=2*	sign=1*	count=0*	return=4*	CARRY=1*.globl smod,mod,ASSERTFAIL*.globl mrabs*smod:	leas	-4(s)*	std	right(s)*	bne	nozero*	swi2*	.byte	ASSERTFAIL*nozero:	jsr	mrabs*mod:	clr	count(s)	| prescale divisor*	inc	count(s)*mscl:	inc	count(s)*	aslb*	rola*	bpl	mscl*	std	right(s)*	ldd	left(s)*	clr	left(s)*	clr	left+1(s)*mod1:	subd	right(s)	| check subtract*	bcc	mod2*	addd	right(s)*	andcc	#~CARRY*	bra	mod3*mod2:	orcc	#CARRY*mod3:	rol	left+1(s)	| roll in carry*	rol	left(s)*	lsr	right(s)*	ror	right+1(s)*	dec	count(s)*	bne	mod1*	tst	sign(s)		| sign fiddle*	beq	nochg*	nega*	negb*	sbca	#0*nochg:	std	right(s)	| move return addr*	ldd	return(s)*	std	left(s)*	ldd	right(s)*	leas	6(s)*	rts*|	mrabs.  converts both args to unsigned, and*|	remembers result sign as the sign of the left*|	argument.  (for signed modulo)*|	result d contains right, sign is non-zero*|	if result (from mod) should be negative.*|*|*.globl mrabs*	left=8.*	right=4.*	sign=3.*mrabs:	clr	sign(s)*	ldd	left(s)*	bge	tryr*	nega*	negb*	sbca	#0*	std	left(s)*	inc	sign(s)*tryr:	ldd	right(s)*	bge	done*	nega*	negb*	sbca	#0*	std	right(s)*done:	rts******************************************************** Case statement support* Case table is of the form:* 	FDB char_value, label* 	FDB char_value, label* 	FDB label,0* That is, it consist of word pairs.* The first word of a pair is the switch value.* The second word of a pair is the label to jump to.* The last pair is special -- the second word is zero* and the first word is the label for the default case,* if there is one, else it is the label on the code* following the switch.* Note that this form is different than that for v2 SmallC. * TBD document the calling parameters* entry : D contains switch value, *			@ stackptr is address of jump table* exit  : exit is a jump *			stackptr is entry stackptr + 2 ( stack is restored*			to as it was before caller pushed switch value.)* cccase* Not implemented yet.* v2 code is readily available but table format differs.* 6809 version was lost.******************************************************* Unknown use, relics ???_etext*	.bss _eend*	.data *_brkend:	.wval	_eend _edata	******************************************************	OPT	l#endasm/* end C include file */