1

我正在寻找一种经济高效的方式来访问我的 6502 表中的记录。该表长 8 个字节。使用间接 Y,我可以偏移字段,但我想要一种方法来获取下一个第 0 条记录。

我曾想过:

lda #id
adc #$08
tax ; now x = x + 8

我见过其他人使用 ASL,而累加器的值是 2 的幂:

asl a
tax ; x = x * 2

如果我只有 2 条记录,那就太好了,但如果我再次 ASL,结果将是 x = 32。这将是一个太远的偏移量。

有没有比使用 ADC 更好的方法来做到这一点?

4

2 回答 2

4

如果表实际上是几个 8 字节的记录,我会将它存储为 8 个 1 字节的记录表,这样可以有效地进行索引。

即数组结构,而不是结构数组

这具有允许仅使用寄存器偏移量对 256 条记录进行索引的优点,并且还可以在不更改地址计算的情况下使用不同大小的记录(因此,如果您想要 5 字节记录,则只需使用更少的数组,而不是更改计算)。

LDA ELEMENT1,Y ; This is an array of the first bytes of our record
STA $1000
LDA ELEMENT2,Y ; This is the second bytes...
STA $1001
...etc...
INY            ; Just need to inc Y to access next record

由于INX/INY是 2 周期指令,因此您不会在更新索引时击败它。

这是我的主要建议,因为它既快速又简单,尽管它确实意味着重新格式化您的数据。

如果这不是一个选项,您可以动态地重新格式化数据(假设您要访问它使其物有所值,并且您有空间这样做),或者您可以使用各种技术,具体取决于您实际想要访问数据的方式以及性能的重要性。

如果您确实需要向索引添加任意数量,而不仅仅是递增,那么简单的方法是:

TYA      (2)
CLC      (2)
ADC #amt (2)
TAY      (2)

然而,那个幼稚的版本需要 8 个周期。如果您省略了 clear-carry,您可以在 6 个周期内执行此操作,您可以在您知道它已被清除的情况下执行此操作(例如,如果遵循一些其他循环计算,其中处于循环中意味着进位没有已生成)。因此,为了避免设置标志,需要调整代码。任何小于 4 的递增都可以简单地通过多次递增来完成。

如果您不能保证清除进位,但您可以在内存中为查找表腾出一个页面,那么您可以在该页面的字节中存储 0 -> 255 并执行以下操作:

LDA table + amt, Y (4)
TAY                (2)

进位标志不是由它设置的,但是零标志是,所以如果表绕到零,你可以检查一下。

如果你必须索引一个地址,那么你可以这样做:

LDA (zeropagevector), Y

并增加zeropagevector. 但是,读取需要 5 个周期。如果您只在一条指令中读取记录,您可以简单地使用普通的绝对寻址,并修改指令本身的地址,从而节省一个周期。

基本上,在 6502 中有很多方法可以优化这种事情,但这实际上取决于您的数据到底是什么以及您希望如何访问它。

于 2013-01-09T19:13:46.317 回答
1

你需要有 2 个字节(16 位)的表指针变量是你的数据比 256 字节块长。

    tablePointerLo = $fa ; example zeropage value
    tablePointerHi = $fb ; example zeropage value

    tableAddress = $1000 ; example table address

    tableLength = 100*8 ; example length
    tableEnd = tableAddress + tableLength

    lda #<tableAddress
    sta tablePointerLo
    lda #>tableAddress
    sta tablePointerHi

loop02:
    ldy #$00
loop01:
    lda (tablePointerLo),y
    sta anywhereYouWant,y
    iny
    cpy #$08
    bne loop01

    lda tablePointerLo
    clc
    adc #$08
    sta tablePointerLo
    bcc pass01
    inc tablePointerHi
pass01:

    ; do whatever you want here with the datas

    lda tablePointerLo
    cmp #<tableEnd
    bne loop02
    lda tablePointerHi
    cmp #>tableEnd
    bne loop02

我没有测试代码,它可能不起作用,但你应该明白主要思想。

于 2013-01-10T08:15:29.623 回答