首页 > 解决方案 > 在 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

标签: loops6502

解决方案


看起来您正在增加存储在的值$00,但您不应该进行操作Y吗?就像是:

        *=$8001

        LDA #<$0400      ; store $0400 into $00 and $01
        STA $00
        LDA #>$0400
        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 #<$0400    ; store $0400 into addr and addr+1
        STA addr
        LDA #>$0400
        STA addr+1

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

更新 1

您的原始代码对我来说似乎工作得很好。请注意,在 C64 仿真器中进行测试时,范围$0400-$0480对应于屏幕内存(参见例如此内存映射),因此当返回 BASIC 时,该范围将被覆盖。例如,当您的代码加载到 时$8001,我在监视器中看到以下代码(假设我们将地址存储在$FBand中$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                                                    

推荐阅读