memory base driver for 6280 3/3

同名の記事 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 をいれることで暇な時間を有効活用できます.

アセンブラの最適化はパズルとしてはおもしろい

これを組むのに時間かけすぎです. 業務としてはよくないです.