为什么我的 Fibonacci 6502 在 144 和 233 时出现故障?
Why is my Fibonacci 6502 malfunctioning for 144 and 233?
以下程序:
PORTB = 00
PORTA = 01
DDRB = 02
DDRA = 03
E = %10000000
RW = %01000000
RS = %00100000
VARX = 00
VARY = 01
VARZ = 02
NUM = 05
DIV = 06
RES = 07
MOD = 08
BACK_TO_FRONT = 20
.org 00
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 #[=10=]
sta VARX
lda #
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 #[=10=]
store_digits:
jmp divide
return_from_div:
lda MOD
sta BACK_TO_FRONT, x
inx
lda RES
sta NUM
lda #[=10=]
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 #
bcc print_digits
ldx #[=10=]
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 #[=10=]
sta RES
lda #[=10=]
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 c0c
.word $cc4c
.word $ac2c
.word $ec6c
.word c1c
.org $fffc
.word reset
.word [=10=]00
在 65C02(WDC 版本)上运行。连接到 ROM(从地址 0x8000 开始)和 RAM 芯片(地址 0x4000)和连接到 HD44780(1602 标准 LCD)的 VIA(65C22)。
程序有效,但部分有效。它输出 1 然后 2 然后 3 ... 然后 89 而不是 144 打印 1,而不是 233 打印 2。然后 1 再然后 98 ???然后是61.
您决定返回 print_digits
的方式不正确:
; I've omitted the SEC since it's pointless
cpx #
bcc print_digits
仅当 X
无符号小于 1 时,才会跳转到 print_digits
。唯一可能为真的值是 0,因此以上也可以描述为跳转到print_digits
如果 X
等于 0。
如果我们查看整个 print_digits
循环,则可以使用以下伪代码对其进行描述:
x = numDigits - 1;
do
{
print(digits[x]);
x--;
} while (x == 0);
只有当 numDigits
为 1 或 2 时,才会给出正确的输出。对于任何大于此值的值,您将打印一位数字,然后退出循环。
你真正想要的是这样的:
x = numDigits - 1;
do
{
print(digits[x]);
x--;
} while (x >= 0);
即替换为:
dex
sec
cpx #
bcc print_digits
与:
dex ; Updates the N flag after decrementing X
bpl print_digits ; Jump if N is clear, i.e. if X >= 0
以下程序:
PORTB = 00
PORTA = 01
DDRB = 02
DDRA = 03
E = %10000000
RW = %01000000
RS = %00100000
VARX = 00
VARY = 01
VARZ = 02
NUM = 05
DIV = 06
RES = 07
MOD = 08
BACK_TO_FRONT = 20
.org 00
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 #[=10=]
sta VARX
lda #
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 #[=10=]
store_digits:
jmp divide
return_from_div:
lda MOD
sta BACK_TO_FRONT, x
inx
lda RES
sta NUM
lda #[=10=]
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 #
bcc print_digits
ldx #[=10=]
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 #[=10=]
sta RES
lda #[=10=]
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 c0c
.word $cc4c
.word $ac2c
.word $ec6c
.word c1c
.org $fffc
.word reset
.word [=10=]00
在 65C02(WDC 版本)上运行。连接到 ROM(从地址 0x8000 开始)和 RAM 芯片(地址 0x4000)和连接到 HD44780(1602 标准 LCD)的 VIA(65C22)。
程序有效,但部分有效。它输出 1 然后 2 然后 3 ... 然后 89 而不是 144 打印 1,而不是 233 打印 2。然后 1 再然后 98 ???然后是61.
您决定返回 print_digits
的方式不正确:
; I've omitted the SEC since it's pointless
cpx #
bcc print_digits
仅当 X
无符号小于 1 时,才会跳转到 print_digits
。唯一可能为真的值是 0,因此以上也可以描述为跳转到print_digits
如果 X
等于 0。
如果我们查看整个 print_digits
循环,则可以使用以下伪代码对其进行描述:
x = numDigits - 1;
do
{
print(digits[x]);
x--;
} while (x == 0);
只有当 numDigits
为 1 或 2 时,才会给出正确的输出。对于任何大于此值的值,您将打印一位数字,然后退出循环。
你真正想要的是这样的:
x = numDigits - 1;
do
{
print(digits[x]);
x--;
} while (x >= 0);
即替换为:
dex
sec
cpx #
bcc print_digits
与:
dex ; Updates the N flag after decrementing X
bpl print_digits ; Jump if N is clear, i.e. if X >= 0