Below is my self modifying routine for memory copy on Commodore 64.
I wrote char codes
and number of repeats
in a table and filled the screen_ram the with this routine.
I'm looking for suggestions for optimization. My priority is memory in this case.
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
Correct increment of instruction's address should be made like this:
address=*+1
lda self_modifying_address
inc address+0
bne *+5
inc address+1
thus probably neglecting all memory savings for self-modified code.
I suggest another approach, that includes self-modifying instruction addresses only where absolulety necessary and also stores memory variables in the instructions.
.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
JMP fetchNewData
-> BEQ fetchNewData
. Move INC sourceAddress
after BEQ end
and there is no need from CPX #0
(after LDX
). 3 bytes less.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With