ADC
和SBC
指令的行为可以通过在处理器状态寄存器中设置或清除十进制模式标志来修改。通常,十进制模式被禁用,ADC/SBC
执行简单的二进制运算(例如$99 + $01 => $9A进位= 0
),但是如果通过SED
指令设置该标志,处理器将执行二进制编码的十进制运算(例如$99 + $01 => $00
进位= )。
要使16位加/减代码以十进制模式工作,只需在开始时包含SED
,在结束时包含CLD
(使处理器恢复正常)。
; 16 bit Binary Code Decimal Addition
SED ;Set decimal mode flag
CLC ;Ensure carry is clear
LDA VLA+0 ;Add the two least significant bytes
ADC VLB+0
STA RES+0 ;... and store the result
LDA VLA+1 ;Add the two most significant bytes
ADC VLB+1 ;... and any propagated carry bit
STA RES+1 ;... and store the result
CLD ;Clear decimal mode
二进制编码的值更容易转换为可显示的数字,并且对于保存诸如高分之类的数字很有用。
; Print the BCD value in A as two ASCII digits
PHA ;Save the BCD value
LSR A ;Shift the four most significant bits
LSR A ;... into the four least significant
LSR A
LSR A
ORA #'0' ;Make an ASCII digit
JSR PRINT ;... and print it
PLA ;Recover the BCD value
AND #$0F ;Mask out all but the bottom 4 bits
ORA #'0' ;Make an ASCII digit
JSR PRINT ;... and print it
BCD
的另一个用途是将二进制值转换为十进制的1。一些算法通过计算二进制值在下位之前减去10000、1000、100、10和1的次数来实现这种转换,但是我通常使用一个简单的固定循环,每次将二进制值中的位移出一个,并将其添加到在每次迭代中被翻倍(在BCD
中)的中间结果。
; Convert an 16 bit binary value into a 24bit BCD value
BIN2BCD LDA #0 ;Clear the result area
STA RES+0
STA RES+1
STA RES+2
LDX #16 ;Setup the bit counter
SED ;Enter decimal mode
_LOOP ASL VAL+0 ;Shift a bit out of the binary
ROL VAL+1 ;... value
LDA RES+0 ;And add it into the result, doubling
ADC RES+0 ;... it at the same time
STA RES+0
LDA RES+1
ADC RES+1
STA RES+1
LDA RES+2
ADC RES+2
STA RES+2
DEX ;More bits to process?
BNE _LOOP
CLD ;Leave decimal mode
十进制算术的最后一个奇数用途是将十六进制数字转换为可打印的ASCII字符。执行这种转换的通常方法是将$30
加到数字($00 - $0F
)上,得到一个中间结果,然后检查该结果是否大于或等于$3A
。如果是,则添加额外的$06
,使结果落在$41 - $46
的范围内。A
-F
)。
; Convert a hex digit ($00-$0F) to ASCII ('0'-'9' or 'A'-'F')
HEX2ASC ORA #$30 ;Form the basic character code
CMP #$3A ;Does the result need adjustment?
BCC .+4
ADC #$05 ;Add 6 (5 and the carry) if needed
结果表明,在十进制模式下,处理器在加法之后进行了基本相同的校正,并且使用正确的参数,我们可以将数字转换为它的ASCII字符,而不需要执行任何比较,如下面的代码所示。
; Convert a hex digit ($00-$0F) to ASCII ('0'-'9' or 'A'-'F')
HEX2ASC SED ;Enter BCD mode
CLC ;Ensure the carry is clear
ADC #$90 ;Produce $90-$99 (C=0) or $00-$05 (C=1)
ADC #$40 ;Produce $30-$39 or $41-$46
CLD ;Leave BCD mode
网友评论