5

以下は、Commodore 64 でのメモリ コピーの自己修正ルーチンです。

char codesテーブルにandを書き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
4

3 に答える 3

3

命令のアドレスを正しくインクリメントするには、次のようにします。

address=*+1
    lda self_modifying_address
    inc address+0
    bne *+5
    inc address+1

したがって、おそらく自己修正コードのすべてのメモリ節約を無視しています。

絶対性が必要な場合にのみ自己変更命令アドレスを含み、命令にメモリ変数を格納する別のアプローチを提案します。

.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
于 2016-02-11T05:32:30.713 に答える
1

i486 の提案に加えて、data_tableが 128 個の値 (終端 0,0 を含む) に制限されている場合は、自己変更LDAs を回避し、代わりに Y レジスタを使用することで、数バイト (および多くのサイクル) を節約できます。

以下にすべてを示しました。値を 2 つの別々のテーブルにINY入れることで、別のバイトを節約する (1 つを削除する) こともできます。data_table

または、 Y を使用して index を使用できるかもしれませんがSCREEN_RAM、私は C64 の人ではありません ...

  ldy #0
fetchNewData:
  lda data_table,y  ; read char value into A
  iny               ; [could remove if two tables]
  ldx data_table,y  ; read repeat value into x
  beq end           ; finish copying [x=0]
  iny

  destination=*+1
- sta SCREEN_RAM
  inc destination
  dex
  bne -
  beq fetchNewData

end:
  rts   

; data format:  <char>,<number of repeats>,[<char>,<number of repeats>,...],00,00

data_table: 
!by 01,03,02,02,......,00,00
于 2016-02-11T02:13:27.557 に答える