2017-10-10 82 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