⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 printf.c

📁 一款MP3 Player Firmware 的原代码,非常有参考价值
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Fast printf routine for use with sdcc/mcs51 * Copyright (c) 2001, Paul Stoffregen, paul@pjrc.com * * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#define LONG_INT#define FIELD_WIDTH// extern void putchar(char );// #define COUT 0x0030// #define PHEX 0x0034// #define PHEX16 0x0036// #define NEWLINE 0x003A#define COUT 0x2030#define PHEX 0x2034#define PHEX16 0x2036#define NEWLINE 0x203Astatic bit long_flag, short_flag, print_zero_flag, negative_flag;#ifdef FIELD_WIDTHstatic bit field_width_flag;static bit leading_zero_flag;static data unsigned char field_width;#endifbit at 0x1F debug;void printfd(code char *fmt, ...) reentrant{        fmt;    /* suppress unreferenced variable warning */        if (debug == 0) return;        _asm ljmp printf_begin _endasm;}void printf(code char *fmt, ...) reentrant{	fmt;	/* supress unreferenced variable warning */	_asmprintf_begin:	mov	a, _bp		// r0 will point to va_args (stack)	add	a, #253	mov	r0, a		// r0 points to MSB of fmt	mov	dph, @r0	dec	r0	mov	dpl, @r0	// dptr has address of fmt	dec	r0printf_main_loop:	clr	a	movc	a, @a+dptr	// get next byte of fmt string	inc	dptr	//cjne	a, #'%', printf_normal	cjne	a, #37, printf_normalprintf_format:	clr	_long_flag	clr	_short_flag	clr	_print_zero_flag	clr	_negative_flag#ifdef FIELD_WIDTH	clr	_field_width_flag	clr	_leading_zero_flag	mov	_field_width, #0#endifprintf_format_loop:	clr	a	movc	a, @a+dptr	// get next byte of data format	inc	dptr	/* parse and consume the field width digits, even if */	/* we don't build the code to make use of them */	add	a, #198	jc	printf_nondigit1	add	a, #10	jnc	printf_nondigit2#ifdef FIELD_WIDTHprintf_digit:	jnz	printf_digit_2	cjne	a, _field_width, printf_digit_2	setb	_leading_zero_flagprintf_digit_2:	setb	_field_width_flag	mov	r1, a	mov	a, _field_width	mov	b, #10	mul	ab	add	a, r1	mov	_field_width, a#endif	sjmp	printf_format_loopprintf_nondigit1:	add	a, #10printf_nondigit2:	add	a, #48printf_format_l:	//cjne	a, #'l', printf_format_h	cjne	a, #108, printf_format_h	setb	_long_flag	sjmp	printf_format_loopprintf_format_h:	//cjne	a, #'h', printf_format_s	cjne	a, #104, printf_format_s	setb	_short_flag	sjmp	printf_format_loopprintf_format_s:	//cjne	a, #'s', printf_format_d	cjne	a, #115, printf_format_d	ljmp	printf_stringprintf_format_d:	//cjne	a, #'d', printf_format_u	cjne	a, #100, printf_format_u	lcall	printf_get_int	ljmp	printf_intprintf_format_u:	//cjne	a, #'u', printf_format_c	cjne	a, #117, printf_format_c	lcall	printf_get_int	ljmp	printf_uintprintf_format_c:	//cjne	a, #'c', printf_format_x	cjne	a, #99, printf_format_x	mov	a, @r0		// Acc has the character to print	dec	r0	sjmp	printf_charprintf_format_x:	//cjne	a, #'x', printf_normal	cjne	a, #120, printf_normal	ljmp	printf_hexprintf_normal:	jz	printf_eotprintf_char:	lcall	printf_putchar	sjmp	printf_main_loopprintf_eot:	ljmp	printf_end	/* print a string... just grab each byte with __gptrget */	/* the user much pass a 24 bit _generic pointer */printf_string:	push	dph		// save addr in fmt onto stack	push	dpl	mov	b, @r0		// b has type of address (_generic *)	dec	r0	mov	dph, @r0	dec	r0	mov	dpl, @r0	// dptr has address of user's string	dec	r0#ifdef FIELD_WIDTH	jnb	_field_width_flag, printf_str_loop	clr	_leading_zero_flag	// never leading zeros for strings	push	dpl	push	dphprintf_str_fw_loop:	lcall	__gptrget	jz	printf_str_space	inc	dptr	dec	_field_width	mov	a, _field_width	jnz	printf_str_fw_loopprintf_str_space:	lcall	printf_space	pop	dph	pop	dpl#endif // FIELD_WIDTHprintf_str_loop:	lcall	__gptrget	jz	printf_str_done	inc	dptr	lcall	printf_putchar	sjmp	printf_str_loopprintf_str_done:	pop	dpl		// restore addr withing fmt	pop	dph	ljmp	printf_main_loop	/* printing in hex is easy because sdcc pushes the LSB first */printf_hex:	lcall	printf_hex8	jb	_short_flag, printf_hex_end	lcall	printf_hex8	jnb	_long_flag, printf_hex_end	lcall	printf_hex8	lcall	printf_hex8printf_hex_end:	lcall	printf_zero	ljmp	printf_main_loopprintf_hex8:	mov	a, @r0	lcall	printf_phex_msn	mov	a, @r0	dec	r0	ljmp	printf_phex_lsn#ifndef LONG_INTprintf_ld_in_hex:	//mov	a, #'0'	mov	a, #48	lcall	printf_putchar	//mov	a, #'x'	mov	a, #120	lcall	printf_putchar	mov	a, r0	add	a, #4	mov	r0, a	sjmp	printf_hex#endif	/* printing an integer is not so easy.  For a signed int */	/* check if it is negative and print the minus sign and */	/* invert it to a positive integer */printf_int:	mov	a, r5	jnb	acc.7, printf_uint	/* check if negative */	setb	_negative_flag	mov	a, r1			/* invert integer */	cpl	a	addc	a, #1	mov	r1, a	jb	_short_flag, printf_uint	mov	a, r2	cpl	a	addc	a, #0	mov	r2, a	jnb	_long_flag, printf_uint	mov	a, r3	cpl	a	addc	a, #0	mov	r3, a	mov	a, r4	cpl	a	addc	a, #0	mov	r4, a	/* printing integers is a lot of work... because it takes so */	/* long, the first thing to do is make sure we're doing as */	/* little work as possible, then convert the binary int to */	/* packed BCD, and finally print each digit of the BCD number */printf_uint:	jb	_short_flag, printf_uint_ck8	jnb	_long_flag, printf_uint_ck16printf_uint_ck32:	/* it's a 32 bit int... but if the upper 16 bits are zero */	/* we can treat it like a 16 bit integer and convert much faster */#ifdef LONG_INT	mov	a, r3	jnz	printf_uint_begin	mov	a, r4	jnz	printf_uint_begin#else	mov	a, r3	jnz	printf_ld_in_hex	;print long integer as hex	mov	a, r4			;rather than just the low 16 bits	jnz	printf_ld_in_hex#endif	clr	_long_flagprintf_uint_ck16:	/* it's a 16 bit int... but if the upper 8 bits are zero */	/* we can treat it like a 8 bit integer and convert much faster */	mov	a, r2	jnz	printf_uint_begin	setb	_short_flagprintf_uint_ck8:	/* it's an 8 bit int... if it's zero, it's a lot faster to just */	/* print the digit zero and skip all the hard work! */	mov	a, r1	jnz	printf_uint_begin#ifdef FIELD_WIDTH	jnb	_field_width_flag, printf_uint_zero	dec	_field_width	lcall	printf_space#endifprintf_uint_zero:	//mov	a, #'0'	mov	a, #48	lcall	printf_putchar	ljmp	printf_main_loopprintf_uint_begin:	push	dpl	push	dph	lcall	printf_int2bcd		// bcd number in r3/r2/r7/r6/r5#ifdef FIELD_WIDTH	jnb	_field_width_flag, printf_uifw_end#ifdef LONG_INTprintf_uifw_32:	mov	r1, #10	jnb	_long_flag, printf_uifw_16	mov	a, r3	anl	a, #0xF0	jnz	printf_uifw_sub	dec	r1	mov	a, r3	anl	a, #0x0F	jnz	printf_uifw_sub	dec	r1	mov	a, r2	anl	a, #0xF0	jnz	printf_uifw_sub	dec	r1	mov	a, r2	anl	a, #0x0F	jnz	printf_uifw_sub	dec	r1	mov	a, r7	anl	a, #0xF0	jnz	printf_uifw_sub#endifprintf_uifw_16:	mov	r1, #5	jb	_short_flag, printf_uifw_8	mov	a, r7	anl	a, #0x0F	jnz	printf_uifw_sub	dec	r1	mov	a, r6	anl	a, #0xF0	jnz	printf_uifw_subprintf_uifw_8:	mov	r1, #3	mov	a, r6	anl	a, #0x0F	jnz	printf_uifw_sub	dec	r1	mov	a, r5	anl	a, #0xF0	jnz	printf_uifw_sub	dec	r1printf_uifw_sub:	;r1 has the number of digits for the number	mov	a, _field_width	mov	c, _negative_flag	subb	a, r1	jc	printf_uifw_end	mov	_field_width, a#ifdef LONG_INT	push	ar3	push	ar2#endif	push	ar7	push	ar6	push	ar5	lcall	printf_space	pop	ar5	pop	ar6	pop	ar7#ifdef LONG_INT	pop	ar2	pop	ar3#endifprintf_uifw_end:#endifprintf_uint_doit:	jnb	_negative_flag, printf_uint_pos	//mov	a, #"-"	mov	a, #45	lcall	printf_putcharprintf_uint_pos:	jb	_short_flag, printf_uint8#ifdef LONG_INT	jnb	_long_flag, printf_uint16printf_uint32:	push	ar5	push	ar6	push	ar7	mov	dpl, r2	mov	a, r3	mov	dph, a	lcall	printf_phex_msn	mov	a, dph	lcall	printf_phex_lsn	mov	a, dpl	lcall	printf_phex_msn	mov	a, dpl	lcall	printf_phex_lsn	pop	acc	mov	dpl, a	lcall	printf_phex_msn	mov	a, dpl	pop	dph	pop	dpl	sjmp	printf_uint16a#endifprintf_uint16:	mov	dpl, r5	mov	dph, r6	mov	a, r7printf_uint16a:	lcall	printf_phex_lsn	mov	a, dph	lcall	printf_phex_msn	mov	a, dph	sjmp	printf_uint8aprintf_uint8:	mov	dpl, r5	mov	a, r6printf_uint8a:	lcall	printf_phex_lsn	mov	a, dpl	lcall	printf_phex_msn	mov	a, dpl	lcall	printf_phex_lsn	lcall	printf_zero	pop	dph	pop	dpl	ljmp	printf_main_loop	/* read an integer into r1/r2/r3/r4, and msb into r5 */printf_get_int:	mov	a, @r0	mov	r1, a	mov	r5, a	dec	r0	jb	_short_flag, printf_get_done	mov	r2, ar1	mov	a, @r0	mov	r1, a	dec	r0	jnb	_long_flag, printf_get_done

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -