NewsProductsSprinterSupportDownloadSprinter ForumAbout usLinksSite map Russian site
Support
 Updates | Knowledge base | Manuals | Resellers | Warranties | Feedback

Knowledge Base

[ Back ] [ Index ] [ Categories ] [ Next ]

Q10022. Routine (Ascii2Word) of converting an ASCIIZ buffer with numbers to a word.

More information

Routine converts an ASCIIZ number to a 2-byte value. The number can have a prefix character to preset the number base. In case of hex numbers, the letter case does NOT matter. This routine DOES NOT deal with negative or fractional numbers. All returned values are positive. The routine will work with values in the range 0 - 65,535 (dec), 0 - FFFF (hex), 0 - 177777 (oct), or 0 - 1111 1111 1111 1111 (bin).

Prefix:
"@": Means OCTAL number follows (ex: @345; bad ex: @87)
"#": Means HEXADECIMAL number follows (ex: #F00f; bad ex: #G0)
"%": Means BINARY number follows (ex: %1010; bad ex: %5)
'no prefix': Default, for DECIMAL numbers (ex: 987; bad ex: 3A57)

Assembler

Any assembler.

Input

(SP+2) -> ASCIIZ string starting address
(SP+0) -> Normal return address

Output

Carry flag reset: Operation was successful.
A=Lo-byte of converted word
HL=Converted word
Carry flag set: Error (overflow or invalid char in buffer)

Routine

Ascii2Word:	POP	HL		;Fetch ret addr briefly
		EX	(SP),HL		;Exchg Ret (SP) with BufferAddr (HL)
A2W_Init:	LD	DE,0		;Reset...
		LD	(A2W_RetVal),DE	;...return value
		LD	A,(HL)		;Get first char in buffer
		LD	C,0Fh		;Prepare for HEX
		CP	"#"		;Is HEX prefix?
		JR	Z,A2W_Nxt	;Jump if so
		LD	C,07h		;Prepare for OCT
		CP	"@"		;Is OCT prefix?
		JR	Z,A2W_Nxt	;Jump if so
		LD	C,01h		;Prepare for BIN
		CP	"%"		;Is BIN prefix?
		JR	Z,A2W_Nxt	;Jump if so
		LD	C,09h		;Ok, number is DEC
		DEC	HL		;Compensate for next INC HL
A2W_Nxt:	INC	HL		;Point to next char in buffer
		LD	A,(HL)		;Char to A
		CP	0h		;End of string?
		JR	Z,A2W_Done	;Jump if so
		PUSH	HL		;Save buffer address while adding
		LD	HL,(A2W_RetVal)	;Get return value so far
		PUSH	HL		;Copy HL to...
		POP	DE		;... register DE
		LD	B,C		;Get loop index to B
A2W_Add:	ADC	HL,DE		;Perform sum...
		DJNZ	A2W_Add		;... B times
		JR	C,A2W_Ovfl	;Abort if overflow
		SUB	"0"		;Convert ASCII in A to number
		CP	9		;Less than 9?
		JR	C,A2W_Chk	;Jump if so.
		RES	5,A		;Force char uppercase (just in case)
		SUB	7		;Deduct "A" - "9" diff.
A2W_Chk:	LD	E,A		;Save number to E
		LD	D,0		;Reset hi-byte of DE
		INC	C		;Test if...
		CP	C		;... A > C, and...
		JR	NC,A2W_Ovfl	;... abort if so...
		DEC	C		;... 'cos it's invalid char.
		XOR	A		;Clear carry flag for next ADC
		ADC	HL,DE		;Add the number to the return value
		JR	C,A2W_Ovfl	;Jump if overflow
		LD	(A2W_RetVal),HL	;Store result so far
		POP	HL		;Fetch back string pointer
		JR	A2W_Nxt		;Keep looping
A2W_Ovfl:	SCF			;Set carry flag to say "Error!"
		POP	HL		;Stack balancing
		RET			;Return to caller
A2W_Done:	LD	HL,(A2W_RetVal)	;Fetch return value
		LD	A,L		;Lo-byte of result to A
		RET			;Back to caller

A2W_RetVal:	DEFW	0000h		;Return value storage

Added by

Marcelo Lopez

14 May 2003.
PETERS PLUS LTD.

[ Back ] [ Index ] [ Categories ] [ Next ]