2017-10-10 80 views
0

对不起,如果这个问题似乎是'太基本'。我是一个68K ASM编码器,但有一位朋友要求我浏览一下6502代码。 我们有一个指向一串数据:阅读内存和公司(6502)

my_ptr ds 2 

此指针设置与此代码:

ldx sound_channel_busy 
bne .abc_set_score1 ; at bottom of code 
sta my_ptr ; fill the pointer 

读取数据与

lda (my_ptr),y ; my_ptr + offset 

这样做,但我看到的6502 doc,y是一个字节。因此,使用超过255字节的数据字符串是不可能的(我们要读取10.000字节或更多的字符串) 我建议我的朋友这样做:

1)设置一个指针为 “碱基” 和临时其中之一在读取

my_ptr ds 2 
my_ptr_tmp ds 2 

2我们将INC)初始将它们与:

ldx sound_channel_busy 
bne .abc_set_score1 
sta my_ptr 
sta my_ptr_tmp ; Duplicate 

3)然后读取使用:

lda (my_ptr_tmp) ; Read to acumulator 
    inc my_ptr_tmp  ; One more on adress pointer 

但它不工作,因为我的朋友是一个C开发,我们没有调试器...不容易。 在68K这似乎是合乎逻辑的,但在6502?

非常感谢您的帮助

回答

1

6502是8位数据,16位地址,所以你的指针需要为2个字节,一般在零页。

lda #<addr ;low byte 
sta my_ptr 
sta my_ptr_tmp 
lda #>addr ;high byte 
sta my_ptr+1 
sta my_ptr_tmp+1 

的增量也需要16位:

inc my_ptr_tmp 
bne :skip 
inc my_ptr_tmp+1 ;only inc high byte if low byte is zero 
:skip 

另外请注意,LDA(ZP)无X或Y仅适用于65C02可用。

+0

嗯......在你的答案的第一部分,这意味着你读取2个字节。但在我的情况下,我有一个2字节的地址,我只想从中读取一个地址。所以我认为问题来自于地址的增加(你在解释中解释了你的答案的一部分)。我对吗? (我会试着回来)。非常感谢。 – Peter

+0

所以这意味着68K中的moveword必须在这里用两个移动字节完成。用于复制prt并且还包含它。非常感谢 – Peter

+0

是的,我认为你说的是​​正确的。数据是字节还是字?正如你所看到的,65(C)02代码几乎是RISC,所以代码根据上下文确实改变(注册使用等)。如果你详细说明你的用例,我可以充实我的示例代码。例如,如果数据未被终止(可能是声音样本的情况),则可能需要递减两字节计数器。 –

5

6502相当有限。

  • 所有的读取和写入内存的8位
  • 所有算术是8位
  • 只有两种间接方式:(zp),y(zp,x) wherer zp是零页面地址。前者计算地址为

    contentOf(zp + (zp + 1) << 8) + y 
    

    并使用它的字节作为操作数。后者计算地址作为

    contentOf(zp + x + (zp + x + 1) << 8) 
    

的Y形成用于访问数组的元素指向零页指针和X形式用于在零页存储器访问矢量表。

要设置指针:

lda #<pointer ; The low byte of the 16 bit address pointer is loaded into A 
    sta my_ptr 
    lda #>pointer ; the high byte of the pointer 
    sta my_ptr+1 
    ldy #0  ; zero the y register 

要访问指针

loopStart: 
    lda (my_ptr),y 

假设一个C风格的字符串用空结束

beq loopExit ; previous LDA sets the S and Z flags. 

递增指针

iny   ; Increment y 
    bne loopStart 
    inc my_ptr+1 
    jmp loopStart 

您也可以将Y保持为0并递增低位字节和两个零页位置,但INC my_ptrINY慢得多,而不是两个周期。

编辑

如果不是空结尾的字符串,你有一个长度,你需要稍微修改此。一种方法是统计你已经完成了多少字节,并与长度进行比较。通过上面的算法,Y是计数,如果长度< 256,所以我们可以做的是计数的高字节存储在

; first set up my_ptr, same as before. 
; 
    lda #<pointer ; The low byte of the 16 bit address pointer is loaded into A 
    sta my_ptr 
    lda #>pointer ; the high byte of the pointer 
    sta my_ptr+1 
; 
; Set up the counter 
; 
    ldx #0  ; set up x for the count 
    ldy #0  ; Set up y for the count/loop 
; 
; A common trick with compiling while loops is to put the test at the end of the loop and jump to it immediately. 
; This means you don't have to reverse the logic of the loop condition. 
; 
    jmp loopTest ; Omit this if you definitely need to go round the loop at least once 
loopStart: 
    lda (my_ptr),y ; Get the byte 
; 
; Do what you need to do here 
; 
; Increment the counter 
; 
    iny   ; Increment y 
    bne loopTest 
    inx 
    inc my_ptr+1 
loopTest: 
    cpy length ; Compare the low byte of length to the count 
    bne loopStart 
    cpx length+1 ; Compare the high byte of length to the count 
    bne loopStart 
+0

使用y和o 0的情况下,该指针似乎是一个很好的窍门的想法。谢谢! – Peter

+0

我想说我想到了它,但是回到当天,这是6502编程中非常常见的技术。 – JeremyP