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

📄 util.asm

📁 8051 VARIOUS UTILITY FUNCTIONSUTIL_ADCAD - Add Acc to DPTR, sets CYUTIL_ADCBAD - Add B/A to DPTR, se
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;  On Exit:
;	Acc Has Entry Value Converted To BCD
;
;  Affected:
;	PSW.CY, PSW.Z, PSW.P, Acc
;
;  Stack:
;	1 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	Values Greater Than 99 Will Not Work Properly.
;
UTIL_BINTOBCD	proc
		push	b			; Save B
		mov	b,#10			; Divide By 10
		div	ab			; Do Divide
		swap	a			; Move Result To High Of A
		orl	a,b			; OR In Remainder
		pop	b			; Recover B
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	Convert Value In Acc From Hex To BCD.  
;
;  Entry Requirements:
;	Acc Has Value To Convert To BCD
;
;  On Exit:
;	DPTR Has Value Of Acc In BCD
;
;  Affected:
;	PSW.CY, PSW.Z, PSW.P, Acc, DPTR
;
;  Stack:
;	2 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	Values Greater Than 255 Will Not Work Properly.  If Acc == 12, DPTR
;	== 0012.  If Acc = 255, DPTR = 0255.
;
UTIL_BINTOBCD12	proc
		push	b			; Save B
		push	acc			; Save Acc
		mov	b,#100			; Divide By 100
		div	ab			; Do Divide
		mov	dph,a			; Store In DPH
		pop	acc			; Recover Acc
		mov	b,#10			; Divide By 10
		div	ab			; Do Divide
		swap	a			; Move Result To High Of A
		orl	a,b			; OR In Remainder
		mov	dpl,a			; Move To DPL
		pop	b			; Recover B
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	Convert 16 Bit Binary Value In DPTR To A Signed Decimal Number String.
;
;  Entry Requirements:
;	DPTR Has Value To Print As A Signed Decimal Number In External Memory
;
;  On Exit:
;	DPTR Points To Start Of Printable String
;
;  Affected:
;	PSW.Z, PSW.P, Acc
;
;  Stack:
;	11 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	Buffer Is In External Memory, And Needs 7 Bytes (Sign, Plus 5 Digits
;	Plus ETX Terminator).  Buffer Is Defined At The End Of The File.
;	The Return String Is ETX Terminated.  Since Result Is Returned In
;	Buffer, It Will Need To Be Copied Or Saved If Additional Calls Are
;	Made, Since The Buffer Will Be Overwritten.
;
UTIL_BINTODEC	proc
		push	psw			; Save PSW
		push	0			; Save R0
		push	1			; Save R1
		push	2			; Save R2
		push	3			; Save R3
		push	4			; Save R4
		push	5			; Save R5
		push	6			; Save R6
		push	7			; Save R7
;
		mov	r6,dph			; Store High In R6
		mov	r7,dpl			; Store Low In R7
		mov	dptr,#X_BUFFER		; Point To Buffer
;
		mov	a,r6			; Get High Of Value
		jnb	acc.7,l?p1		; If <= 32767, Skip
		clr	c			; Clear For SUBB
		clr	a			; Clear For SUBB
		subb	a,r7			; Subtract Low
		mov	r7,a			; Move Back
		clr	a			; Clear For SUBB
		subb	a,r6			; Subtract High
		mov	r6,a			; Move Back
		mov	a,#'-'			; Number Is Negative
		movx	@dptr,a			; Store Sign
		inc	dptr			; Next Location
;
;  DPTR Contains Value From 0..32767. 
;
l?p1		mov	r0,#high 10000		; 10^5
		mov	r1,#low  10000		; 10^5
		clr	f0			; Haven't Stored Non-0 Value
;
;  R0/R1 Now Has Factor
;
l?p2		mov	r2,6			; Get Value To R2
		mov	r3,7			; Get Value To R3
		mov	r4,0			; Get Factor
		mov	r5,1			; Get Factor
		call	UTIL_UDIV		; Divide Value By Factor
		mov	r6,4			; Store Remainder High
		mov	r7,5			; Store Remainder Low
;
;  Quotient In R4/R5 Should Be In 0..9 Range.  If 0, Don't Store Unless We've
;  Stored A Previous Non-Zero Value
;
		mov	a,r3			; Get Low Of Quotient
		jnz	l?p3			; If Not 0, Store It
		jnb	f0,l?p4			; If No Non-0 Before, Don't Store
l?p3		setb	f0			; Non-0 Value
		call	UTIL_BINTOASC		; Make Printable
		movx	@dptr,a			; Store Character
		inc	dptr			; Next Location
;
;  Now Divide Factor By 10 For Next Time
;
l?p4		mov	r2,0			; Get Factor
		mov	r3,1			; Get Factor
		mov	r4,#high 10		; 10
		mov	r5,#low  10		; 10
		call	UTIL_UDIV		; Factor = Factor / 10
		mov	r0,2			; Update Factor High
		mov	r1,3			; Update Factor Low
;
		mov	a,r0			; Get Factor High
		orl	a,r1			; OR In Factor Low
		jnz	l?p2			; If Not 0, Repeat
;
;  Store The End Of String Marker And Print
;
		jb	f0,l?p5			; If We've Stored A Number, Skip
		mov	a,#'0'			; Put At Least 1 Zero
		movx	@dptr,a			; Store It
		inc	dptr			; Next Location
l?p5		mov	a,#ETX			; End Of String Marker
		movx	@dptr,a			; Store It
;
;  Now Return Pointer To Buffer
;
		mov	dptr,#X_BUFFER		; Point To Print Buffer
;
;  Recover Registers And Exit
;
		pop	7			; Recover R7
		pop	6			; Recover R6
		pop	5			; Recover R5
		pop	4			; Recover R4
		pop	3			; Recover R3
		pop	2			; Recover R2
		pop	1			; Recover R1
		pop	0			; Recover R0
		pop	psw			; Recover PSW
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
; 	Convert Hexadecimal Value In DPTR As A Unsigned Decimal Number.
;	Convert 16 Bit Binary Value In DPTR To An Unsigned Decimal Number 
;	String.
;
;  Entry Requirements:
;	DPTR Has Value To Print As An UnsSigned Decimal Number In External 
;	Memory
;
;  On Exit:
;	DPTR Points To Start Of Printable String
;
;  Affected:
;	PSW.Z, PSW.P, Acc
;
;  Stack:
;	11 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	Buffer Is In External Memory, And Needs 7 Bytes (Sign, Plus 5 Digits
;	Plus ETX Terminator).  Buffer Is Defined At The End Of The File.
;	The Return String Is ETX Terminated.  Since Result Is Returned In
;	Buffer, It Will Need To Be Copied Or Saved If Additional Calls Are
;	Made, Since The Buffer Will Be Overwritten.
;
UTIL_BINTOUDEC	proc
		push	psw			; Save PSW
		push	0			; Save R0
		push	1			; Save R1
		push	2			; Save R2
		push	3			; Save R3
		push	4			; Save R4
		push	5			; Save R5
		push	6			; Save R6
		push	7			; Save R7
;
		mov	r6,dph			; Store High In R6
		mov	r7,dpl			; Store Low In R7
		mov	dptr,#X_BUFFER		; Point To Buffer
;
l?p1		mov	r0,#high 10000		; 10^5
		mov	r1,#low  10000		; 10^5
		clr	f0			; Haven't Stored Non-0 Value
;
;  R0/R1 Now Has Factor
;
l?p2		mov	r2,6			; Get Value To R2
		mov	r3,7			; Get Value To R3
		mov	r4,0			; Get Factor
		mov	r5,1			; Get Factor
		call	UTIL_UDIV		; Divide Value By Factor
		mov	r6,4			; Store Remainder High
		mov	r7,5			; Store Remainder Low
;
;  Quotient In R4/R5 Should Be In 0..9 Range.  If 0, Don't Store Unless We've
;  Stored A Previous Non-Zero Value
;
		mov	a,r3			; Get Low Of Quotient
		jnz	l?p3			; If Not 0, Store It
		jnb	f0,l?p4			; If No Non-0 Before, Don't Store
l?p3		setb	f0			; Non-0 Value
		call	UTIL_BINTOASC		; Make Printable
		movx	@dptr,a			; Store Character
		inc	dptr			; Next Location
;
;  Now Divide Factor By 10 For Next Time
;
l?p4		mov	r2,0			; Get Factor
		mov	r3,1			; Get Factor
		mov	r4,#high 10		; 10
		mov	r5,#low  10		; 10
		call	UTIL_UDIV		; Factor = Factor / 10
		mov	r0,2			; Update Factor High
		mov	r1,3			; Update Factor Low
;
		mov	a,r0			; Get Factor High
		orl	a,r1			; OR In Factor Low
		jnz	l?p2			; If Not 0, Repeat
;
;  Store The End Of String Marker And Print
;
		jb	f0,l?p5			; If We've Stored A Number, Skip
		mov	a,#'0'			; Put At Least 1 Zero
		movx	@dptr,a			; Store It
		inc	dptr			; Next Location
l?p5		mov	a,#ETX			; End Of String Marker
		movx	@dptr,a			; Store It
;
;  Now Return Pointer To Buffer
;
		mov	dptr,#X_BUFFER		; Point To Print Buffer
;
;  Recover Registers And Exit
;
		pop	7			; Recover R7
		pop	6			; Recover R6
		pop	5			; Recover R5
		pop	4			; Recover R4
		pop	3			; Recover R3
		pop	2			; Recover R2
		pop	1			; Recover R1
		pop	0			; Recover R0
		pop	psw			; Recover PSW
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	Acc Contains An ASCII Value.  Determine If Valid Decimal DigitOr Not.
;	If Not, Return Acc Trashed, And CY == 1.  If Digit Is Valid, Return 
;	CY == 0.
;
;  Entry Requirements:
;	Acc Has ASCII Decimal Value To Validate
;
;  On Exit:
;	CY == 0 If Acc = '0'..'9', CY == 1 If Not
;
;  Affected:
;	PSW.CY
;
;  Stack:
;	2 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	None
;
UTIL_VALDCDG	proc
		call	UTIL_TOUPPER		; Make Upper Case
		cjlt	a,#'0',l?p1		; If < '0', Return CY == 1
		cjgt	a,#'9',l?p1		; If > '9', Return CY == 1
		clr	c			; CY == 0 Means Good Digit
		ret				; Return To Caller
;
l?p1		setb	c			; CY == 1 Means Bad Digit
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	Acc Contains An ASCII Value.  Determine If Valid Hex Digit Or Not.
;	If Not, Return Acc Trashed, And CY == 1.  If Digit Is Valid, Return 
;	CY == 0.
;
;  Entry Requirements:
;	Acc Has ASCII Hex Value To Validate
;
;  On Exit:
;	CY == 0 If Acc = '0'..'9', 'a'..'f', 'A'..'F', CY == 1 If Not
;
;  Affected:
;	PSW.CY
;
;  Stack:
;	2 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	None
;
UTIL_VALHXDG	proc
		call	UTIL_TOUPPER		; Make Upper Case
		cjlt	a,#'0',l?p2		; If < '0', Return CY == 1
		cjle	a,#'9',l?p1		; If <= '9', Return CY == 0
		cjlt	a,#'A',l?p2		; If < 'A', Return CY == 1
		cjgt	a,#'F',l?p2		; If > 'F', Return CY == 1
;
l?p1		clr	c			; CY == 0 Means Good Digit
		ret				; Return To Caller
;
l?p2		setb	c			; CY == 1 Means Bad Digit
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	Acc Has Character To Be Validate For A..Z, a..z, 0..9 Range.  
;
;  Entry Requirements:
;	Acc Has Character To Validate As A..Z, a..z, 0..9 Range
;
;  On Exit:
;	Return CY == 0 If Character In Range, Else Return CY == 1.
;
;  Affected:
;	PSW.CY
;
;  Stack:
;	2 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	None
;
UTIL_VALALPHA	proc
		call	UTIL_TOUPPER		; Make Upper Case
		cjlt	a,#'0',l?p2		; If < '0', Return CY == 1
		cjle	a,#'9',l?p1		; If <= '9', Return CY == 0
		cjlt	a,#'A',l?p2		; If < 'A', Return CY == 1
		cjgt	a,#'Z',l?p2		; If > 'Z', Return CY == 1
;
l?p1		clr	c			; CY == 0 Means Good Character
		ret				; Return To Caller
;
l?p2		setb	c			; CY == 1 Means Bad Character
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	DPTR Points To An ETX Terminated String In External Memory.  Verify 
;	That Characters In String Are A..Z, a..z, 0..9.  
;
;  Entry Requirements:
;	DPTR Points To An ETX Terminated String To Search
;
;  On Exit:
;	CY == 0 If No Other Characters, DPTR Points To ETX
;	CY == 1 If Non A..Z, a..z, 0..9 Characters, DPTR Points To Bad Character
;
;  Affected:
;	PSW.CY, DPTR
;
;  Stack:
;	3 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	None
;
UTIL_VALALPHAZ	proc
		push	acc			; Save Acc
l?p1		movx	a,@dptr			; Get Character
		cjeq	a,#ETX,l?p2		; Exit Of End Of String (CY=0)
		call	UTIL_VALALPHA		; Validate Character
		jc	l?p2			; If Error, Exit
		inc	dptr			; Next Character
		jmp	l?p1			; Continue
l?p2		pop	acc			; Recover Acc
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	DPTR Points To An ETX Terminated String In External Memory.  Count 
;	The Number Of ASCII Digits In The String.  If The Number Of Digits 
;	Exceeds 255, Return CY == 1, Else Return Digit Count In Acc And 
;	CY == 0.  DPTR Is Modified.
;
;  Entry Requirements:
;	DPTR Points To ETX Terminated String In External Memory
;
;  On Exit:
;	CY == 0, Acc Has Number Of Digits ('0'..'9') Found
;	CY == 1, Number Of Digits Found Exceeds 255
;	DPTR Points To ETX
;
;  Affected:
;	PSW.CY, PSW.Z, PSW.P, Acc, DPTR
;
;  Stack:
;	1 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	None
;
UTIL_CNTDG	proc
		push	0			; Save R0
		mov	r0,#0			; Clear Counter
l?p1		movx	a,@dptr			; Get Character
		cjeq	a,#ETX,l?p2		; Exit If End Of String
		inc	dptr			; Next Character
		cjlt	a,#'0',l?p1		; Skip If < '0'
		cjgt	a,#'9',l?p1		; Skip If > '9'
		inc	r0			; Increment Counter
		mov	a,r0			; Get Counter
		jnz	l?p1			; Repeat Count
		setb	c			; Too Many Digits
		pop	0			; Recover R0
		ret				; Return To Caller
;
l?p2		mov	a,r0			; Get Count To Acc
		clr	c			; Clear For No Error
		pop	0			; Recover R0
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	Unsigned Divide Of R2/3 By R4/5
;
;  Entry Requirements:
;	Divisor In R4/5
;	Dividend In R2/3
;
;  On Exit:
;	Quotient In R2/3
;	Remainder In R4/5
;
;  Affected:
;	PSW.CY, PSW.Z, PSW.P, Acc, B, R2, R3, R4, R5
;
;  Stack:
;	4 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	None
;
UTIL_UDIV	proc
		push	0			; Save R0
		push	1			; Save R1
		call	DIVIDE			; Divide
		pop	1			; Recover R1
		pop	0			; Recover R0
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	Unsigned Modulus Of R2/3 By R4/5
;
;  Entry Requirements:
;	Divisor In R4/5
;	Dividend In R2/3
;
;  On Exit:
;	Remainder In R4/5, R2/3
;
;  Affected:
;	PSW.CY, PSW.Z, PSW.P, Acc, B, R2, R3, R4, R5
;
;  Stack:
;	4 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	None
;
UTIL_UMOD	proc
		push	0			; Save R0
		push	1			; Save R1
		call	DIVIDE			; Divide
		pop	1			; Recover R1
		pop	0			; Recover R0
		mov	2,r4			; Get Remainder High To R2
		mov	3,r5			; Get Remainder Low To R2
		ret				; Return To Caller
		endproc
;
;****************************************************************************
;
;  Description:
;	Signed Modulus Of R2/3 By R4/5
;
;  Entry Requirements:
;	Divisor In R4/5
;	Dividend In R2/3
;
;  On Exit:
;	Remainder In R2/3
;
;  Affected:
;	PSW.CY, PSW.Z, PSW.P, Acc, B, R2, R3, R4, R5
;
;  Stack:
;	4 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	Swiped From A Now Defunct 'C' Compiler
;
UTIL_MOD	proc
		push	0
		push	1
		mov	a,r4
		xrl	a,r2
		push	acc
		call	NEGEM
		call	DIVIDE
		mov	2,r4
		mov	3,r5
		pop	acc
		jnb	acc.7,l?p1
		clr	a
		clr	c
		subb	a,r3
		mov	r3,a
		clr	a
		subb	a,r2
		mov	r2,a
l?p1		pop	1
		pop	0
		ret
		endproc
;
;****************************************************************************
;
;  Description:
;	Signed Divide Of R2/3 By R4/5
;
;  Entry Requirements:
;	Divisor In R4/5
;	Dividend In R2/3
;
;  On Exit:
;	Quotient In R2/3
;	Remainder In R4/5
;

⌨️ 快捷键说明

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