■ CPUについて Hu65C80は、命令セットの先読みはしていないので安心してよい。 つまり、自己書き換えプログラムは安全に実行できる。(アタリマエカ(^_^;) ※でも、パイプライン処理してるって話を聞いた・・・(1999・11・19追加) ■ ブロック転送命令と割り込みの関係 ブロック転送命令を実行中に割り込みが発生した場合、ブロック転送命令が終了するま で、割り込みは実行されない。(あたりまえの話) ■ スタックについて プッシュ=ストアー→デクリメント プル  =インクリメント→ロード よって、直前にプッシュしたデータを読みたいときは、 tsx lda $2101,x ~ また、 jsr label とした場合のスタックは S+1 : low label S+2 : high label ■ SET 命令について ゼロページのワークエリア _al に対して加算命令をする場合は 例) al=al+12 セット命令を使わない場合 ; BYTE/CYCLE lda _al ; 2/4 adc #12 ; 2/4 sta _al ; 2/4 ; TOTAL 6/12 セット命令を使った場合 ldx #low(_al) ; 2/2 set ; 1/2 adc #12 ; 2/2+3 ; TOTAL 5/9 こうしてみると、断然 SET 命令を使ったほうがよい。 しかし、Xレジスターが未使用の時しか出来ないし、 デバッガー上では混乱するので多様は禁物。 だが、Aレジスターが壊されないのは魅力。 ※SET命令はAレジスタの代わりに2000,xを対象に演算する命令 ■ ブロック転送命令 データをLENGTHバイト転送 * ループによる(255バイト未満) ; byte/cycle clx ; 1/2 loop: lda ABS1,x ; 3/5 sta ABS2,x ; 3/5 inx ; 1/2 cpx #LENGTH ; 2/2 bne loop ; 2/2 2/4 ; TOTAL 20/(2+18*LENGTH-2) * 書き換え方式(ROMの場合) lda #$73 ; 2/2 sta up+0 ; 3/5 2/4 lda #low(ABS1) ; 2/2 sta up+1 ; 3/5 lda #high(ABS1) ; 2/2 sta up+2 ; 3/5 lda #low(ABS2) ; 2/2 sta up+3 ; 3/5 lda #high(ABS2) ; 2/2 sta up+4 ; 3/5 lda #low(LENGTH) ; 2/2 sta up+5 ; 3/5 lda #high(LENGTH) ; 2/2 sta up+6 ; 3/5 lda #$60 ; 2/2 sta up+7 ; 3/5 jsr up ; 3/7 . . . up: tai ABS1,ABS2,LENGTH ; 7/(17+6*LENGTH) rts ; 1/7 ; 書き換え先がアブソリュート TOTAL 51/(87+6*LENGTH) ; 書き換え先がゼロページ TOTAL 43/(79+6*LENGTH) 転送数 6 7 8 16 32 ----------------------------------------------------------------------- cycle ループ(255バイト未満) 108 126 144 288 576 自己書き換え 127 129 133 183 279 8バイト以上転送するときは、自己書き換えを使ったほうが速い。 コードは倍になるが。 ※RAMの場合はjsrの代わりに直接転送命令を書いてもいい ■ ワードデータ転送 普通なら、 ; ABS ZP lda adr1+0 ; 3/5 2/4 sta adr2+0 ; 3/5 2/4 lda adr1+1 ; 3/5 2/4 sta adr2+1 ; 3/5 2/4 ; total 12/20 8/16 ブロック転送を用いると、 tii adr1,adr2,$0002 ; 7/(17+6*2) ; total 7/29 速度は50%弱おちるが、何と最大5バイトもお得!(゚o゚) ゼロページ間でも1バイト得 ■ アブソリュートのイミディエイトワードデータ転送 label0: dw imm ; 2/0 . . tii label0,adr,$0002 ; 7/(17+6*2) . . ; total 9/29 これでやっと1バイトだから、実用にならん。 ■ XレジスターとYレジスターをあわせてワードレジスター扱いにする すると、アドレッシングモードに制約が出来るが、ワード演算をゼロページに 対して行うより高速に行える。 例えば、ゼロページワードANDイミディエイトは、 ldx #low(zp) ; 2/2 set ; 1/2 and #low(imm) ; 2/5 inx ; 1/2 set ; 1/2 and #high(imm) ; 2/5 ; total 9/18 だが、XYを使うと tay ; 1/2 and #low(imm) ; 2/2 tay ; 1/2 tax ; 1/2 and #high(imm) ; 2/2 tax ; 1/2 ; total 8/12 となる。 ■ 2の補数拡張 Aレジスターを2バイトのワーク_axに2の補数拡張する場合、 sta _al ; 2/4 asl a ; 1/2 lda _al ; 2/4 sbc _al ; 2/4 sta _ah ; 2/4 ; total 9/18 これが一番早い。 ■ 割り込み状態の保存 Iフラグが割り込み状態を示すのでPレジスターを保存すればよい。 意外と知らない(知っててやらない?)人が多い。 Dフラグも同様。 php ;; <-割り込み状態の保存 cli ;; <-割り込み禁止 . . . plp ;; <-割り込み状態の復帰 . . .