2026.8.22
前へ
次へ
ホームページトップへ戻る


[新連載開始]W65C02マイコンボードの製作

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
私としてはW65C02をさわるのは全く初めてです。何から何まで未経験です。さてどうなりますでしょうか。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第51回]



●CMP,CPX,CPY●BASICプログラムです

CMPはアキュムレータとメモリまたは即値との大小を比較してその結果をフラグに反映させます。
演算の結果によってNフラグ、Zフラグ、Cフラグがセット、リセットされます。
フラグはA(アキュムレータ)−M(メモリ、即値)の計算の結果と同じですがアキュムレータ、メモリの値は変わりません。
N(Negative)は結果が負のときにセットされ0または正のときリセットされます。
Z(Zero)は結果が0のときにセットされます。
CフラグはSBC命令と同じになります。
A>=MのときC=1、A<MのときC=0になります。
CMPには以下の命令があります。
 ニーモニック  マシン語コード  アセンブラ書式 バイト数 クロック数
 CMP a  CD  CMP $1234  3  4
 CMP a,x  DD  CMP $1234,x   3  4
 CMP a,y  D9  CMP $1234,y  3  4
 CMP #  C9  CMP #$12  2  2
 CMP zp  C5  CMP $12  2  3
 CMP (zp,x)  C1  CMP ($12,x)   2  6
 CMP (zp)  D2  CMP ($12)  2  5
 CMP zp,x  D5  CMP $12,x  2  4
 CMP (zp),y  D1  CMP ($12),y  2  5
a a,x a,y # zp (zp,x) (zp) zp,x (zp),y はアドレッシングモードです。
aは絶対アドレスでzpはゼロページです。
,xはxの値で修飾することを示します。
,yはxの値で修飾することを示します。
#は8ビットの即値です。
16ビットの即値はありません。
()は間接アドレス指定です。
()内で指定するアドレスの値が最終的な下位アドレスになりその次のアドレスの値が最終的な上位アドレスになります。
W65C02のアドレッシングモードは[第4回]で説明していますので適宜参照してください。

CPXはXレジスタとメモリまたは即値との大小を比較してその結果をフラグに反映させます。
X、メモリの値は変わりません。
フラグについてはCMPと同じです。
以下の命令があります。
 ニーモニック  マシン語コード  アセンブラ書式 バイト数 クロック数
 CPX a  EC  CPX $1234  3  4
 CPX #  E0  CPX #$12  2  2
 CPX zp  E4  CPX $12  2  3

CPYはYレジスタとメモリまたは即値との大小を比較してその結果をフラグに反映させます。
Y、メモリの値は変わりません。
フラグについてはCMPと同じです。
以下の命令があります。
 ニーモニック  マシン語コード  アセンブラ書式 バイト数 クロック数
 CPY a  CC  CPY $1234  3  4
 CPY #  C0  CPY #$12  2  2
 CPY zp  C4  CPY $12  2  3

●BASICプログラムです
前回、前々回のクロック毎の動作はPIC18F45K50に組み込んでいるPICUSBIOBASICを使って実現しています。
下がそのBASICプログラムです。
PICBASICを使うとこんなことが簡単にできてしまいます。
   10 picout PORTB,$FE:'reset=0
   20 clk=0
   30 for a=0 to 5
   40 picout PORTE,1
   50 picout PORTE,5
   60 clk=clk+1
   70 c=picin(PORTC):adrsh=and(c,$c0):sy=and(c,$01)
   80 pa=picin(PORTA):adrsl=and(pa,$3f):adrs=adrsh+adrsl
   90 d=picin(PORTD)
  100 print clk,hex$(adrs),hex$(d),hex$(picin(PORTC)),"sync=";sy
  110 next a
  120 picout PORTB,$FF:'reset=1
  130 print "start"
  140 for a=0 to 40
  150 picout PORTE,1
  160 picout PORTE,5
  170 clk=clk+1
  180 c=picin(PORTC):adrsh=and(c,$c0):sy=and(c,$01)
  190 pa=picin(PORTA):adrsl=and(pa,$3f):adrs=adrsh+adrsl
  200 d=picin(PORTD)
  210 print clk,hex$(adrs),hex$(d),hex$(picin(PORTC)),"sync=";sy
  220 if sy=0 goto 240
  230 if d=$DB goto 250
  240 next a
  250 stop
RB0はW65C02のRESETに接続しています。
RB0=0でBASICプログラムを開始します。
picout PORTE,1
picout PORTE,5
でW65C02のCLOCKを↓_↑のように出力します。
RE2がCLOCK出力です。
RE0はPIC18F45K50側からのアドレス出力を禁止する信号です。
常時RE0=1にしておきます。
最初の6回のループはダミーループです。
GoogleによるとW65C02はリセットを保持したまま最低でも2回のクロックが必要とのこと。
そのためのダミーループです。
多めに6CLOCKにしています。
その後にRB0=1にしてリセットを解除します。
そこでprint ”start”を実行しています。
CLOCK#7からがリセット解除後のクロックです。
Googleによるとリセット解除後の5クロックが内部処理で6クロック目と7クロック目でFFFCとFFFDの開始アドレスを読み込んで8クロック目からプログラムの実行を開始するとのこと。
上記BASICプログラムの場合内部処理の5クロックはCLOCK#7〜#11になります。
前回の画面のログでは開始アドレスを読んだのはCLOCK#13、CLOCK#14でプログラムが開始されたのはCLOCK#15からでした。
Googleの説明と1クロックずれていますがリセット解除とクロックとのタイミングが関係しているのかもしれません。
その後は41回ループしています。
ユーザプログラムが無限ループになっているかもしれないことを考慮してのことです。
BASICですからループ回数は簡単に変更できます。
その途中でDB(STP)が読み込まれたらブレークします。
アドレス下位8ビットA7〜A0はRC7、RC6、RA5〜RA0で合成します。
RC0がSYNCです。
RD7〜RD0がD7〜D0です。
BASICはこんなにも簡単なのです。
PICUSBIOBASICはこんなにも優れものなのです。
以上毎度のことながら自画自賛の弁であります。

W65C02マイコンボードの製作[第51回]
2026.8.22 upload

前へ
次へ
ホームページトップへ戻る