Search code examples
assembly6502

Exercise in self modifying memory copy routine, 6502 ASM


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

Solution

  • 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