在 6502 上使用零页间接寻址循环内存

问题描述

我编写了一个小的 6502 程序来循环内存并使用 STA 零页间接寻址将值存储在 128 个连续的内存位置,但该程序似乎无法正常工作。它应该将值 $01 的 128 个副本存储到内存地址 $0400 之后,但它没有。我做错了什么?

        *=$8001

        ; set $00,$01 to $0400
        LDA #$00
        STA $00
        LDA #$04
        STA $01


        CLC             ; Clear carry and decimal mode
        CLD
        LDX #128        ; Loop 128 times
        LDY #0

loop    LDA #$01        ; the value to store
        STA ($00),Y     ; store A to the address held in $00,$01
        
                        ; Add 1 to $00,$01 (16-bit addition)

        LDA $00
        ADC #1
        STA $00
        LDA $01
        ADC #0
        STA $01
                        ; do it 127 more times
        DEX
        BNE loop
        RTS

解决方法

看起来您正在增加 $00 中存储的值,但您不应该操作 Y 吗?类似的东西:

        *=$8001

        LDA #$00      ; store $0400 into $00 and $01
        STA $00
        LDA #$04
        STA $01

        LDY #128      ; load 128 into Y
        LDA #$01      ; load 01 into A
loop    DEY
        STA ($00),Y   ; store A into $0400 + Y
        BNE loop      ; loop until Y is zero
        RTS

在这个循环中,我们去掉 X,将 Y 初始化为 128,然后每次循环迭代递减 Y。这意味着我们正在“向后”填充内存。

注意 1

地址 $00$01 通常是特殊的(例如, 在 C64 上,这些地址控制处理器功能),因此取决于 在您的环境中,您可能需要选择不同的零内存 位置。

注意 2

如果我写这个,我会避免将地址直接硬编码到代码中,而是声明一个命名的存储位置。在本地测试您的代码时,我使用 64tass 和以下代码组装它:

        *=$00fb
addr    .word ?     ; declare two bytes of storage at * and *+1
                    ; I'm using $00fb because this is an unused zero
                    ; page location on the c64 (and I'm testing using
                    ; the VICE emulator).

        *=$8001
        LDA #$00    ; store $0400 into addr and addr+1
        STA addr
        LDA #$04
        STA addr+1

        LDY #128
        LDA #$01
loop    DEY
        STA (addr),Y
        BNE loop
        RTS

更新 1

你的原始代码对我来说似乎很好用。请注意,在 C64 仿真器中进行测试时,范围 $0400-$0480 对应于屏幕内存(参见例如 this memory map),因此当返回 BASIC 时,该范围将被覆盖。例如,在 $8001 加载您的代码后,我会在监视器中看到以下代码(假设我们将地址存储在 $FB$FC 中):

(C:$e5cf) d 8001
.C:8001  A9 00       LDA #$00
.C:8003  85 FB       STA $FB
.C:8005  A9 04       LDA #$04
.C:8007  85 FC       STA $FC
.C:8009  18          CLC
.C:800a  D8          CLD
.C:800b  A2 80       LDX #$80
.C:800d  A0 00       LDY #$00
.C:800f  A9 01       LDA #$01
.C:8011  91 FB       STA ($FB),Y
.C:8013  A5 FB       LDA $FB
.C:8015  69 01       ADC #$01
.C:8017  85 FB       STA $FB
.C:8019  A5 FC       LDA $FC
.C:801b  69 00       ADC #$00
.C:801d  85 FC       STA $FC
.C:801f  CA          DEX
.C:8020  D0 ED       BNE $800F
.C:8022  60          RTS

如果我在 $8022 处放置一个断点并调整代码...

(C:$8029) break 8022
BREAK: 1  C:$8022  (Stop on exec)
(C:$8029) g 8001
#1 (Stop on  exec 8022)  064 011
.C:8022  60          RTS            - A:04 X:00 Y:00 SP:f2 ..-...Z.    4131803

然后检查目标内存范围,里面填满了$01

(C:$8022) m 400,480
>C:0400  01 01 01 01  01 01 01 01  01 01 01 01  01 01 01 01   ................
>C:0410  01 01 01 01  01 01 01 01  01 01 01 01  01 01 01 01   ................
>C:0420  01 01 01 01  01 01 01 01  01 01 01 01  01 01 01 01   ................
>C:0430  01 01 01 01  01 01 01 01  01 01 01 01  01 01 01 01   ................
>C:0440  01 01 01 01  01 01 01 01  01 01 01 01  01 01 01 01   ................
>C:0450  01 01 01 01  01 01 01 01  01 01 01 01  01 01 01 01   ................
>C:0460  01 01 01 01  01 01 01 01  01 01 01 01  01 01 01 01   ................
>C:0470  01 01 01 01  01 01 01 01  01 01 01 01  01 01 01 01   ................
>C:0480  20                                                    

但是一旦我回到 BASIC,它看起来像这样:

(C:$e5d4) m 400,480
>C:0400  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20                   
>C:0410  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20                   
>C:0420  20 20 20 20  20 20 20 20  12 05 01 04  19 2e 20 20           ......  
>C:0430  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20                   
>C:0440  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20                   
>C:0450  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20                   
>C:0460  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20                   
>C:0470  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20                   
>C:0480  20                                                    

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...