下面是我在 Commodore 64 上进行内存复制的自我修改例程。
我写了char codes并number of repeats在一个表中,充满了screen_ram的这个套路。
我正在寻找优化建议。在这种情况下,我的优先事项是内存。
memCopy:
sourceAddress=*+1 ; mark self modifying addrres
fetchNewData:
lda data_table ; read char value into A
ldx data_table+1 ; read repeat value into x
inc sourceAddress
inc sourceAddress
cpx #00 ; if X=0
beq end ; finish copying
destination=*+1
- sta SCREEN_RAM
inc destination
dex
bne -
jmp fetchNewData
end:
rts
; data format: <char>,<number of repeats>,[<char>,<number of repeats>,...],00,00
data_table:
!by 01,03,02,02,......,00,00
Run Code Online (Sandbox Code Playgroud)
指令地址的正确增量应如下所示:
address=*+1
lda self_modifying_address
inc address+0
bne *+5
inc address+1
Run Code Online (Sandbox Code Playgroud)
因此可能忽略了自修改代码的所有内存节省。
我建议另一种方法,仅在需要绝对性的情况下包括自修改指令地址,并将内存变量存储在指令中。
.loop
fetch_ptr=*+1
ldx #0
lda filler_bytes,x ;have two tables, first contains only filler bytes,
ldy repeat_bytes,x ;second only repeat counts
beq .exit
inc fetch_ptr ;this way you save 1 increment
fill_ptr=*+1
ldx #0
.fill
sta SCREEN_RAM,x
inx
bne +
inc .fill+2 ;only self-modify high byte of address in the instruction
+ dey
bne .fill
stx fill_ptr
jmp .loop
.exit
rts
filler_bytes !byte 1,2,3,4,5,4,3,2,1
repeat_bytes !byte 4,4,5,5,6,6,5,5,4,0
Run Code Online (Sandbox Code Playgroud)