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


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

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

[第80回]



●USBによるデータの送受信(2)はじめの一歩

W65C02テストボード上のPIC18F45K50とW65C02との間のデータの送受信についてRAMを介したDMA方式で行なうというアイデアを思いつきました。
その方法で本当に通信がおこなえるのか。
ND80Z3.5ではZ80とPIC18F14K50の間で74HCデータラッチを使って送受信を行なっています。
そこにRAMを置くことで同じことができるように思えます。
果たしてうまくいくのかどうかまずはうんと簡単なプログラムを作って試してみることにしました。
下はW65C02側のテストプログラム(ソースプログラム)です。
;w65c02test52 26/9/22
;
;USB READ/WRITE test1
;
        org $8000
;
        ldx #$00
        txs
;read
loop:
        lda $f3
        beq loop
        lda $f2
        beq end
;write
        inc;testdata
        sta $f4
        lda #$01
        sta $f5
        stz $f3
        bra loop
end:
        stz $f3
        stp
;end

W65C02アセンブラでアセンブルしました。


下はアセンブルした結果生成されたリストファイルです。
0000        ;w65c02test52 26/9/22
0000        ;
0000        ;USB READ/WRITE test1
0000        ;
8000            org $8000
8000        ;
8000 A200       ldx #$00
8002 9A         txs
8003        ;read
8003        loop:
8003 A5F3       lda $f3
8005 F0FC       beq loop
8007 A5F2       lda $f2
8009 F00B       beq end
800B        ;write
800B 1A         inc;testdata
800C 85F4       sta $f4
800E A901       lda #$01
8010 85F5       sta $f5
8012 64F3       stz $f3
8014 80ED       bra loop
8016        end:
8016 64F3       stz $f3
8018 DB         stp
8019        ;end

PIC18F45K50とW65C02との間でデータの送受信を行なうための共通のバッファをゼロページに設けます。
$F2はW65C02の受信バッファです。
PIC18F45K50がDMAによって$F2に書き込んだデータをW65C02が読み取ります。
とりあえずは1バイトだけのバッファです。
PIC18F45K50がデータを書き込んだときにその合図として$F3に#$01を書き込みます。
W65C02がそのデータを読み取ったとき$03を#$00にします。
W65C02からPIC18F45K50に送信するバッファとして$F4と$F5を使います。
W65C02がPIC18F45K50に送信するデータを$F4に書き込みます。
W65C02がデータを書き込んだときにその合図として$F5に#$01を書き込みます。
PIC18F45K50はDMAによって$F4のデータを読み出します。
PIC18F45K50はそのデータを読み取ったとき$05を#$00にします。

下はPIC18F45K50の側のBASICプログラムです。
   10 picout TRISB,0
   20 picout PORTB,$FA
   30 picout TRISC,$0F
   40 picout TRISA,0
   50 picout TRISE,0
   60 picout PORTE,2
   70 picout PORTC,0:'adrsH
   80 picout PORTA,0
   90 picout PORTE,1:'set&not out
  100 picout TRISA,$FF
  110 picout TRISC,$FF
  120 picout TRISD,$FF
  130 picout TRISB,$80
  140 picout PORTB,$FF:'65c02 start
  150 input A
  160 if A=0 goto *end
  170 picout PORTB,$DF:'rdy
  180 picout PORTB,$DB:'be
  190 picout PORTE,0:'adrsH active
  200 picout TRISA,0   210 picout TRISC,0
  220 picout TRISD,0
  230 picout PORTA,$F2:'adrs=f2
  240 picout PORTC,$F2
  250 picout PORTD,A
  260 picout TRISB,0
  270 picout PORTB,$5B:'w
  280 picout PORTB,$DB
  290 picout PORTA,$F3:'adrs=f3
  300 picout PORTC,$F3
  310 picout PORTD,1
  320 picout PORTB,$5B:'w
  330 picout PORTB,$DB
  340 picout PORTE,1
  350 picout TRISA,$FF
  360 picout TRISC,$FF
  370 picout TRISD,$FF
  380 picout TRISB,$80
  390 picout PORTB,$DF
  400 picout PORTB,$FF
  410 *end
  420 print "end"

BASICは簡単な言語なのですがそれでもこういう場合のプログラムは相当に面倒でわかりにくいものになります。
PIC18F45K50がDMAでRAMにアクセスするところは全部PIC18F45K50のI/Oポートを制御することで行なわれます。
本来はPICのマシン語でコントロールするところをBASICに置き換えただけなので手続きとか手順まで簡単になるわけではありません。
PICはI/Oアクセスに特化している反面メモリアクセスには適していません。
普通のCPUならばMEMREAD、MEMWRITEなどのコマンドで1度でできるところをPICではアドレスの出力もデータの入出力もWRやRDなどの信号出力もすべてI/Oポートの入出力で行なわなければなりません。
その手続きを手順を追って行なうのはなかなかに面倒な作業です。
それに加えてこれから行なおうとする作業はW65C02の存在を考慮したうえでW65C02側のプログラムとぶつかったりしないように工夫しながらW65C02との間でデータのやりとりを行わなければなりません。
たった1バイトの送信、受信をするだけでも上のような長ったらしいプログラムになってしまいます。
この手順、手続きは必要なものなのでマシン語で記述したとしても同じことです。
BASICのメリットはその命令が何をしているのかがわかる点にあります。
しかしそれだけではまだ不足です。
PORTBからFAをOUTしていることはわかったとしてもそれだけでは何をしているのかはわかりません。
ということで私自身の覚えを兼ねてコメントを書いておきます。
あわせて回路図も参照してください。
回路図は[第69回]にあります。
先頭の数字は行番号です。
10 PORTBを出力に設定
20 W65C02をリセット(RB0、RESET=0)、バスを開放(RB2、BE=0)
30〜50 PORTA、PORTC、PORTEを出力に設定
60〜90 PIC18F45K50側のアドレスA15〜A8を00に固定、バスへの出力は禁止(RE0=1)
100〜120 PORTA、PORTC、PORTDを入力に設定(バスへの出力を禁止)
130 RB7を入力に設定(WR出力を禁止)
140 RESET、BE解除(W65C02スタート)
ここからPIC18F45K50側からデータ(1バイト)をW65C02に送る作業
150 1バイトのデータを入力
160 入力データが0の時はプログラムを終了する(終了処理は未完)
170 W65C02の実行を一時停止(RB5、RDY=0)
180 W65C02のバスを開放(RB2、BE=0)
これでDMAが可能になる
190 A15〜A8出力アクティブ(A15〜A8は60〜90で00にしている。ゼロページアクセスのため)
200〜220 PORTA、PORTC、PORTDを出力に設定(バスへの出力可)
230〜280 アドレスF2に150の入力データを書き込む WRはRB7(RB7は130で入力に設定しているのでここで出力に設定する)
290〜330 アドレスF3に01を書き込む
ここまででDMAを終了する
340 A15〜A8出力を禁止
350〜370 PORTA、PORTC、PORTDを入力に設定(バスへの出力を禁止)
380 RB7を入力に設定(WR出力を禁止)
390 W65C02のバス出力可(RB2、BE=1)
400 W65C02の実行停止を解除(RB5、RDY=1)
本来はこの後にDMAで$F4のW65C02側のデータを読み取ってからGOTO 150で処理を繰り返すところだがテストなのでこのまま終了する
なおW65C02側のプログラムはループしている

プログラムを実行しました。

この画面にはありませんが先にW65C02側のプログラム65C02TEST52.BINは$8000に/LDコマンドでロードしてあります。
この画面ではBASICプログラムはまだ作成中ですがRENコマンドで行番号を整理して/SAVEコマンドでRWTEST1.TXTとしてセーブしました。
RUNでBASICプログラムの実行を開始しました。
A?の表示にテストデータとして$34を入力しました。
BASICプログラムはここで終了します。
まだW65C02側のプログラムは動いているはずなので/STOPでW65C02をリセットしました。
/CMで$F2〜$F5を確認しました。
$F2にはBASICプログラムで34を書き、$F3には01を書いたのですがW65C02がデータを読み取ったしるしとしてそこが00になつています。
W65C02は読み取ったデータをINC命令で+1してそれを$F4に書き込み$F5に01を書きます。
/CMの実行によつてそのようになつていることが確認できました。
これでDMAによってデータの送受信ができることが確認できました。
今回のプログラムを参考にすることでUSB送受信プログラムをユーザーが自分なりのプログラムとして作成することが可能になります。
その仕組みはそのまま残すことにしますが。
基本的な手続きの流れを把握するのはよしとしましてこのBASICプログラムの手続きはあまりに面倒です。
次回はそこのところをなんとか工夫してみることにします。

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

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