问题
我正在查看一个6502程序,它具有多个字节数组(与特定声音相对应的音效数据),这些数组具有不同的长度。目前,这涉及显式迭代第一个数组(如果排队),然后是第二个等等,并且每个声音都有一个单独的音量,延迟等变量集,因此代码设置为使用这些硬编码标签。
我想将其合并到循环中,索引这些额外的变量和音效数据。索引变量相当简单,可以使用索引寻址,但是索引音效数据需要更多的工作,我想知道是否在应用索引间接和间接索引寻址时遗漏了什么。
以下是我目前正在执行的自包含示例。如果可能的话,我希望缩紧LoadFromTable
中的代码,最好使用X
和Y
寻址:
.equ Ptr0, 0x80
.equ Ptr1, 0x81
.org 0xFE00
.org 0x0000
Init:
LDX #0xFF
TXS
Main:
LDX #0x00
LDY #0x00
JSR LoadFromTable
; A should be 'H', 0x48
LDX #0x01
LDY #0x00
JSR LoadFromTable
; A should be 'B', 0x42
LDX #0x02
LDY #0x02
JSR LoadFromTable
; A should be 'A', 0x41
JMP Main
LoadFromTable:
TXA ; Double outer index to account for 16 bit pointers
ASL ; "
TAX ; "
LDA Table,X ; Load the low byte of the array into a pointer
STA Ptr0 ; "
INX ; Load the high byte of the array into the pointer
LDA Table,X ; "
STA Ptr1 ; "
LDA (Ptr0),Y ; Load the character at the inner index into the array
RTS
.org 0x0040
Table:
.word Item0
.word Item1
.word Item2
.org 0x0080
Item0:
.byte 'H', 'E', 'L', 'L', 'O', 0x00
Item1:
.byte 'B', 'O', 'N', 'J', 'O', 'U', 'R', 0x00
Item2:
.byte 'C', 'I', 'A', 'O', 0x00
.org 0x00FA
.word Init
.word Init
.word Init
实现
借鉴@NickWestgate的分离表格想法和@Michael指出的初始指针计算,我已经从以下代码中进行了改进:
PROCESS_MUSIC:
; ...
BNE MusDoB
MusChanA:
; ...
LDA MUSICA,X
BNE MusCmdToneA
; ...
JMP MusChanA
MusCmdToneA:
; ...
BNE MusNoteA
; ...
MusNoteA:
; ...
LDA MUSICA,X
; ...
MusDoB:
; ...
BNE MusDoDone
MusChanB:
; ...
LDA MUSICB,X
BNE MusCmdToneB
; ...
JMP MusChanB
MusCmdToneB:
; ...
BNE MusNoteB
; ...
MusNoteB:
; ...
MusDoDone:
RTS
转化为更通用的子程序:
PROCESS_MUSIC:
LDX #0x01
PerChannel:
; ...
BNE EndPerChannel
LDA MusicTableL,X
STA tmp0
LDA MusicTableH,X
STA tmp1
MusChan:
; ...
LDA (tmp0),Y
BNE MusCmdTone
; ...
BEQ MusChan
MusCmdTone:
; ...
BNE MusNote
; ...
MusNote:
; ...
LDA (tmp0),Y
; ...
EndPerChannel:
DEX
BPL PerChannel
RTS
增加以下表格:
MusicTableL:
.byte <MUSICA
.byte <MUSICB
MusicTableH:
.byte >MUSICA
.byte >MUSICB
这样做就不需要我之前一直使用的
LoadFromTable
函数了,而且整体看起来更加简洁。
Ptr0/1
似乎非常低效(也就是说,只需要在切换到新的音效时才这么做)。 - MichaelINX
/INY
会设置进位标志)。 - msbitLDA(Ptr0),Y
,因此它可以直接内联。 - msbit