【发布时间】:2020-05-22 03:29:45
【问题描述】:
以下程序:
PORTB = $6000
PORTA = $6001
DDRB = $6002
DDRA = $6003
E = %10000000
RW = %01000000
RS = %00100000
VARX = $4000
VARY = $4001
VARZ = $4002
NUM = $4005
DIV = $4006
RES = $4007
MOD = $4008
BACK_TO_FRONT = $4020
.org $8000
reset:
lda #%11111111 ; Set all pins on port A to output
sta DDRA
lda #%11100000 ; Set top 3 pins on port B to output
sta DDRB
lda #%00011100 ; Set 8-bit mode; 2-line display; 5x8 font
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #E ; Set E bit to send instruction
sta PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #%01110000 ; Display on; cursor on; blink off
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #E ; Set E bit to send instruction
sta PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #%01100000 ; Increment and shift cursor; don't shift display
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #E ; Set E bit to send instruction
sta PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #$0
sta VARX
lda #$1
sta VARY
lda #$a
sta DIV
loop:
lda VARX
clv
clc
adc VARY
clc
clv
sta VARZ
lda VARY
sta VARX
lda VARZ
sta VARY
lda VARY
sta NUM
ldx #$0
store_digits:
jmp divide
return_from_div:
lda MOD
sta BACK_TO_FRONT, x
inx
lda RES
sta NUM
lda #$0
cmp NUM
bcc store_digits
dex
print_digits:
ldy BACK_TO_FRONT, x
lda digit_table, y
sta PORTA
lda #RS ; Set RS; Clear RW/E bits
sta PORTB
lda #(RS | E) ; Set E bit to send instruction
sta PORTB
lda #RS ; Clear E bits
sta PORTB
dex
sec
cpx #$1
bcc print_digits
ldx #$0
delay:
lda #%00000100
sta PORTA
lda #RS ; Set RS; Clear RW/E bits
sta PORTB
lda #(RS | E) ; Set E bit to send instruction
sta PORTB
lda #RS ; Clear E bits
sta PORTB
cpx #$f
beq next
inx
jmp delay
next:
lda #%10000000
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #E ; Set E bit to send instruction
sta PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTB
jmp loop
divide:
lda #$0
sta RES
lda #$0
sta MOD
div_loop:
lda NUM
cmp DIV
bcc answer
lda NUM
sec
sbc DIV
clc
clv
sta NUM
inc RES
jmp div_loop
answer:
lda NUM
sta MOD
jmp return_from_div
digit_table:
.word $8c0c
.word $cc4c
.word $ac2c
.word $ec6c
.word $9c1c
.org $fffc
.word reset
.word $0000
在 65C02(WDC 版本)上运行。连接到 ROM(从地址 0x8000 开始)和 RAM 芯片(地址 0x4000)和连接到 HD44780(1602 标准 LCD)的 VIA (65C22)。
该程序有效,但只是部分有效。它输出 1 然后 2 然后 3 ... 然后 89 而不是 144 打印 1,而不是 233 打印 2. 然后 1 再然后 98 ???然后是 61。
【问题讨论】:
-
cpx #$1 / bcc print_digits看起来不对。为什么你只想在X unsigned lower than 1时继续打印数字?由于dex更新了N标志,您应该能够用bpl print_digits替换打印循环的最后3 条指令。 -
还有什么特殊原因导致您不使用
jsr/rts像往常一样从divide调用和返回? -
BPL = 在 Plus 上的分支,所以 dex 递减,直到它达到 0,然后再减 1。并且设置了负标志,因此不再设置跳跃。使用我想要的密件抄送(而 x 大于 1)。显然我得到了相反的结果:-) 它从 1 中减去 x 不?不像我想的那样来自 x 的 1?
-
但是您在打印每个数字之后 递减 X,因此只要 X >= 0,您就希望保持循环,即使用
BPL。 -
您当前的代码基本上对应于
x = numDigits-1; do { print(digits[x]); x--; } while (x == 0);这显然只适用于由 1 位或 2 位数字组成的数字。