同名の記事 1/3 の "メモリデータの受信" を高速化できました. 2/3 の "書き込みルーチン" はいろいろ試しましたが劇的な効果は得られなかったので前回の物が最適のようです.
コードは read_optimize が 1,2,4,8 で異なるマクロを使ってます.
read_optimize equ 8 ;7.0 sec ;read_optimize equ 1 ;7.6 sec cly ldx #%10 read_byte_next: (ここにシフトレジスタからの読み込みコードが入る) sta (<mb128_destsrc),y iny bne read_byte_next inc <mb128_destsrc+1 inc <mb128_length+0 bne read_byte_next inc <mb128_length+1 bne read_byte_next rts
read_optimize = 1,2,4
lda #1<<7 read_bit_next rept read_optimize stz joypad stx joypad nop nop lsr joypad ror a endm bcc read_bit_next
- 最初の lda #1<<7 は前回同様ループカウンタの初期化です.
- 2度の nop はシフトレジスタの立ち上がりから 4 CSH clocks が必要なので挿入します. 3 CSH clocks も試しましたがダメでした.
今回はいろいろ考えて lsr joypad としました. lsr mem 命令の場合は下記の3つの処理をします.
- joypad を read.
- read した data をシフト. temp = {1'b0, temp[7:1]}, C = temp[0]; とする.
- (いらない) シフトしたデータを write する.
3 番目の不要な write は動作不安定の原因になると思って前回は避けていたのですが読み込み処理としては, clock が 1->0 または 1->1 になることは次の処理として問題ないです. data はずっと don't care です.
lda joypad; から ror a の間に txa などを挟む必要がなくなりましてとてもすっきりました.
read_optimize == 8
i eval 0 rept read_optimize stz joypad stx joypad if i == 0 nop else ror a endif nop lsr joypad if i == 7 ror a endif i eval i + 1 endm
- この命令はループがなくマクロで繰り返すので lda #1<<7 が不要になりました.
- 2度 nop を挟む場所に可能なら ror a をいれることで暇な時間を有効活用できます.
アセンブラの最適化はパズルとしてはおもしろい
これを組むのに時間かけすぎです. 業務としてはよくないです.