?? convert.asm
字號:
; ********************************************************
; * Number conversion routines, Version 0.1 January 2002 *
; * (C)2002 by info@avr-asm-tutorial.net *
; ********************************************************
;
; The following rules apply for all conversion routines:
; - Errors during conversion set the T-bit in the status
; register.
; - Z points to either SRAM (Z>=$0060) or to registers
; ($0001 .. $001D, exclude R0, R16 and R30/31).
; - ASCII- and BCD-coded numbers with multiple digits are
; placed with higher significant digits at lower adres-
; ses. Z should always point to the most significant
; digit.
; - 16-bit-binary values are generally located in the
; registers rBin1H:rBin1L. These must be defined within
; the calling program.
; - Register rmp (range: R16..R29) is used within the
; routines, its content is changed.
; - Register pair Z is used within the routines, its
; content is set depending on the result.
; - Some routines use register R0 temporarily, its content
; is restored.
; - Due to the use of the Z-Register pair the header file
; for the target processor (xxxxdef.inc) must be inclu-
; ded in the calling program or ZH (R31) and ZL (R30)
; must be defined manually. Otherwise an error message
; results, or you will get crazy things going on, when
; you run the program.
; - Because subroutines and push/pop-operations are used
; within these routines you must set the stack pointer
; (SPH:SPL, resp. SPL for devices with equal or less
; than 256 Byte internal SRAM).
;
; ***************** Routines Overview ********************
; Routines Input Conditions Out, Errors
; --------------------------------------------------------
; AscToBin2 Z points on stops at first non- 16-bit-bin
; first ASCII non-decimal digit, rBin1H:L,
; char ignores leading Overflow
; blanks and zeros
; Asc5ToBin2 Z points on requires exact 5 16-bit-bin
; first ASCII valid digits, rBin1H:L,
; char ignores leading Overflow
; blanks and zeros and non-dec
; Bcd5ToBin2 5-digit-BCD requires exact 5 16-bit-bin
; Z points to valid digits rBin1H:L
; first digit Overflow
; and non-BCD
; Bin2ToBcd5 16-bit-bin Z points to first 5-digit-BCD
; in rBin1H:L BCD digit Z on first,
; no errors
; Bin2ToHex4 16-bit-bin Z points to first 4-digit-hex
; in rBin1H:L Hex ASCII digit, Z on first
; hex digits A..F no errors
; Hex4ToBin2 4-digit-hex Z points to first 16-bit-bin
; Z points to hex ASCII digit, rBin1H:L,
; first char requires 4 digits, invalid hex
; A..F or a..f ok digit
; ******************* Conversion code ********************
;
; Package I: From ASCII resp. BCD to binary
;
; AscToBin2
; =========
; converts an ASCII coded number to a 2-Byte bi-
; nary
; In: Z points to first digit, conversion stops at first
; digit detected or if overflow of the result occurs,
; end of number must be terminated by a non-decimal
; ASCII-digit!
; Out: Z points to first non-valid digit or to the digit
; where the overflow occurred, if number is valid the
; T-Flag is clear and the number is in registers
; rBin1H:rBin1L
; Used registers: rBin1H:L (result), rBin2H:L (restored
; after use), rmp
; Called subroutines: Bin1Mul10
;
AscToBin2:
clr rBin1H ; Clear the result
clr rBin1L
clt ; Clear error flag bit
AscToBin2a:
ld rmp,Z+ ; ignore leading blanks and zeros
cpi rmp,' ' ; blank?
breq AscToBin2a
cpi rmp,'0' ; zero?
breq AscToBin2a
AscToBin2b:
subi rmp,'0' ; subtract ASCII zero
brcs AscToBin2d ; End of the number
cpi rmp,10 ; check invalid digit
brcc AscToBin2d ; No-decimal char
rcall Bin1Mul10 ; Multiply binary number by 10
brts AscToBin2c ; overflow, return with T-Flag set
add rBin1L,rmp ; add the digit to the binary
ld rmp,Z+ ; read next char
brcc AscToBin2b ; no overflow to binary MSB
inc rBin1H ; Overflow to binary MSB
brne AscToBin2b ; no overflow of binary MSB
set ; Set overflow flag
AscToBin2c:
sbiw ZL,1 ; Back one char, last char end/invalid
AscToBin2d:
ret
;
; Asc5ToBin2
; ==========
; converts a 5-digit ASCII to a 16-bit-binary
; In: Z points to first decimal ASCII-digit, leading
; blanks and zeros are ok. Requires exact 5 digits.
; Result: T-Flag reports result:
; T=0: result in rBin1H:rBin1L, valid, Z points to
; first digit of the hex-ASCII-number
; T=1: error, Z points to the first illegal character
; or to the digit, where the overflow occurred
; Used registers: rBin1H:L (result), R0 (restored after
; use), rBin2H:L (restored after use), rmp
; Called subroutines: Bin1Mul10
;
Asc5ToBin2:
push R0 ; R0 is used as counter, save it first
ldi rmp,6 ; five chars, one too much
mov R0,rmp
clr rBin1H ; Clear result
clr rBin1L
clt ; Clear T-Bit
Asc5ToBin2a:
dec R0 ; all chars read?
breq Asc5ToBin2d ; last char
ld rmp,Z+ ; read a char
cpi rmp,' ' ; ignore blanks
breq Asc5ToBin2a ; next char
cpi rmp,'0' ; ignore leading zeros
breq Asc5ToBin2a ; next char
Asc5ToBin2b:
subi rmp,'0' ; treat digit
brcs Asc5ToBin2e ; Last char was invalid
cpi rmp,10 ; digit > 9
brcc Asc5ToBin2e ; Last char invalid
rcall Bin1Mul10 ; Multiply result by 10
brts Asc5ToBin2e ; Overflow occurred
add rBin1L,rmp ; add the digit
ld rmp,z+
brcc Asc5ToBin2c ; no overflow to MSB
inc rBin1H ; Overflow to MSB
breq Asc5ToBin2e ; Overflow of MSB
Asc5ToBin2c:
dec R0 ; downcount number of digits
brne Asc5ToBin2b ; convert more chars
Asc5ToBin2d: ; End of ASCII number reached ok
sbiw ZL,5 ; Restore start position of ASCII number
pop R0 ; Restore register R0
ret
Asc5ToBin2e: ; Last char was invalid
sbiw ZL,1 ; Point to invalid char
pop R0 ; Restore register R0
set ; Set T-Flag for error
ret ; and return with error condition set
;
; Bcd5ToBin2
; ==========
; converts a 5-bit-BCD to a 16-bit-binary
; In: Z points to the most signifant digit of the BCD
; Out: T-flag shows general result:
; T=0: Binary in rBin1H:L is valid, Z points to the
; first digit of the BCD converted
; T=1: Error during conversion. Either the BCD was too
; big (must be 0..65535, Z points to BCD where the
; overflow occurred) or an illegal BCD was detected
; (Z points to the first non-BCD digit).
; Used registers: rBin1H:L (result), R0 (restored after
; use), rBin2H:L (restored after use), rmp
; Called subroutines: Bin1Mul10
;
Bcd5ToBin2:
push R0 ; Save register
clr rBin1H ; Empty result
clr rBin1L
ldi rmp,5 ; Set counter to 5
mov R0,rmp
clt ; Clear error flag
Bcd5ToBin2a:
ld rmp,Z+ ; Read BCD digit
cpi rmp,10 ; is it valid?
brcc Bcd5ToBin2c ; invalid BCD
rcall Bin1Mul10 ; Multiply result by 10
brts Bcd5ToBin2c ; Overflow occurred
add rBin1L,rmp ; add digit
brcc Bcd5ToBin2b ; No overflow to MSB
inc rBin1H ; Overflow to MSB
breq Bcd5ToBin2c ; Overflow of MSB
Bcd5ToBin2b:
dec R0 ; another digit?
brne Bcd5ToBin2a ; Yes
pop R0 ; Restore register
sbiw ZL,5 ; Set to first BCD digit
ret ; Return
Bcd5ToBin2c:
sbiw ZL,1 ; back one digit
pop R0 ; Restore register
set ; Set T-flag, error
ret ; and return
;
; Bin1Mul10
; =========
; multiplies a 16-bit-binary by 10
; Sub used by: AscToBin2, Asc5ToBin2, Bcd5ToBin2
; In: 16-bit-binary in rBin1H:L
; Out: T-flag shows general result:
; T=0: Valid result, 16-bit-binary in rBin1H:L ok
; T=1: Overflow occurred, number too big
;
Bin1Mul10:
push rBin2H ; Save the register of 16-bit-binary 2
push rBin2L
mov rBin2H,rBin1H ; Copy the number
mov rBin2L,rBin1L
add rBin1L,rBin1L ; Multiply by 2
adc rBin1H,rBin1H
brcs Bin1Mul10b ; overflow, get out of here
Bin1Mul10a:
add rBin1L,rbin1L ; again multiply by 2 (4*number reached)
adc rBin1H,rBin1H
brcs Bin1Mul10b ; overflow, get out of here
add rBin1L,rBin2L ; add the copied number (5*number reached)
adc rBin1H,rBin2H
brcs Bin1Mul10b ;overflow, get out of here
add rBin1L,rBin1L ; again multiply by 2 (10*number reached)
adc rBin1H,rBin1H
brcc Bin1Mul10c ; no overflow occurred, don't set T-flag
Bin1Mul10b:
set ; an overflow occurred during multplication
Bin1Mul10c:
pop rBin2L ; Restore the registers of 16-bit-binary 2
pop rBin2H
ret
;
; *************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -