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

Looping through memory using Zero Page indirect addressing on the 6502

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

        *=01

        ; set [=10=], to 00
        LDA #[=10=]
        STA [=10=]
        LDA #
        STA 


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

loop    LDA #        ; the value to store
        STA ([=10=]),Y     ; store A to the address held in [=10=],
        
                        ; Add 1 to [=10=], (16-bit addition)

        LDA [=10=]
        ADC #1
        STA [=10=]
        LDA 
        ADC #0
        STA 
                        ; do it 127 more times
        DEX
        BNE loop
        RTS

看起来您正在递增 [=16=] 中存储的值,但您不应该改为操纵 Y 吗?类似于:

        *=01

        LDA #<00      ; store 00 into [=10=] and 
        STA [=10=]
        LDA #>00
        STA 

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

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

备注 1

地址 [=16=]</code> 通常很特殊(例如, 在 C64 上,这些地址控制处理器功能),因此取决于 在您的环境中,您可能需要选择不同的零内存 地点。</p> <h2>注2</h2> <p>如果我写这个,我会避免将地址直接硬编码到代码中,而是声明一个命名的存储位置。在本地测试您的代码时,我使用 <a href="http://tass64.sourceforge.net/" rel="nofollow noreferrer">64tass</a> 和以下代码组装它:</p> <pre><code> *=[=11=]fb addr .word ? ; declare two bytes of storage at * and *+1 ; I'm using [=11=]fb because this is an unused zero ; page location on the c64 (and I'm testing using ; the VICE emulator). *=01 LDA #<00 ; store 00 into addr and addr+1 STA addr LDA #>00 STA addr+1 LDY #128 LDA # loop DEY STA (addr),Y BNE loop RTS


更新 1

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

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

如果我在 22 处放置断点并调整代码...

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

然后检查目标内存范围,里面填满了</code>:</p> <pre><code>(C:22) 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

但是一旦我 return 到 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