SSブログ
English Version

Z80GALの構想 [Z80]

 PICとZ80を使った3チップ構成のCP/Mボード(Pic24CPM)を開発しましたが、周辺チップをPICで代行せず、GALとソフトでの対応でチップ数の少ないZ80ボードを構想中です。

 ネット上ではRAMまでもマイコン側で受け持とうとする試みもある中で逆行するようですが、Z80でも20MHzで動かせばソフトで周辺チップの機能を代行できるのではないかという発想です。

 まずはシリアル通信ですが、Z80が処理中でもキー入力を受け付けられるようにしたいのでタイマー割込みを使って受信する予定です。

 そのためにはボーレートの3倍でタイマー割込みする必要があり、GAL(22V10D)を使った分周回路を検討してみました。

 CUPLコンパイラはWinCuplを使う予定ですが、Windows10環境では結構不安定で関連する実行ファイルを全て「互換性のトラブルシューティング」で互換性設定することで少し安定するようになりました。

 試行錯誤で作ったCuplソースが下記です。
 PLDによるカウンターの実現に関してはネットで探すといくつか例が見つかりますが、そのままでは使えなかったので「下位ビットが全て'1'の場合、反転する」というようにして論理式を作成することで割合すっきりしたものができました。

GALを使った分周器のCuplソース
Name Z80GAL; Partno SA0001; Date 2020/10/19; Revision 01; Designer skyriver; Company Piclabo; Assembly None; Location None; Device g22V10; /****************************************************************/ /* */ /* freq divider and control signal genelator for Z-80 one borad */ /* by skyriver */ /****************************************************************/ /* GAL22V10 +--- ---+ clock 1| |24 +5V /RESET 2| |23 /INTRQ /MREQ 3| |22 Q7 /IORQ 4| |21 Q6 /RD 5| |20 Q5 /WR 6| |19 Q4 A7 7| |18 Q3 A6 8| |17 Q2 A5 9| |16 Q1 A4 10| |15 Q0 A3 11| |14 NC GND 12| |13 NC +-------+ */ /** Inputs **/ PIN 1 = clock; /* Register Clock */ PIN 2 = !RESET; /* reset */ PIN 3 = !MREQ; /* memory request */ PIN 4 = !IORQ; /* I/O request */ PIN 5 = !RD; /* read */ PIN 6 = !WR; /* write */ PIN [7..11] = [A7..3]; /* address */ /** Outputs **/ PIN 23 = !Q8; /* timer interrupt request */ PIN [15..22] = [Q0..7]; /* counter */ /* NODE [Q0..7]; cann't use NODE !! */ field output = [Q7..0]; field adr = [A7..3]; Q0.d = !Q0; append Q1.d = !Q1 & Q0; append Q1.d = Q1 & !Q0; append Q2.d = !Q2 & Q0 & Q1; append Q2.d = Q2 & (!Q0 # !Q1); append Q3.d = !Q3 & Q0 & Q1 & Q2; append Q3.d = Q3 & (!Q0 # !Q1 # !Q2); append Q4.d = !Q4 & Q0 & Q1 & Q2 & Q3; append Q4.d = Q4 & (!Q0 # !Q1 # !Q2 # !Q3); append Q5.d = !Q5 & Q0 & Q1 & Q2 & Q3 & Q4; append Q5.d = Q5 & (!Q0 # !Q1 # !Q2 # !Q3 # !Q4); append Q6.d = !Q6 & Q0 & Q1 & Q2 & Q3 & Q4 & Q5; append Q6.d = Q6 & (!Q0 # !Q1 # !Q2 # !Q3 # !Q4 # !Q5); append Q7.d = !Q7 & Q0 & Q1 & Q2 & Q3 & Q4 & Q5 & Q6; append Q7.d = Q7 & (!Q0 # !Q1 # !Q2 # !Q3 # !Q4 # !Q5 # !Q6); /*************************************************/ /* baud rate : 14400 */ /* x3 sampling -> 1000000/(38400*3)=8.68[usec] */ /* 20MHz : 1/20[usec] */ /* divid rate */ /* -> 1000000/(38400*3)/(1/20) */ /* = 173.61 */ /*************************************************/ $DEFINE MAXNUM 'd'174 Q0.ar = output:MAXNUM; Q1.ar = output:MAXNUM; Q2.ar = output:MAXNUM; Q3.ar = output:MAXNUM; Q4.ar = output:MAXNUM; Q5.ar = output:MAXNUM; Q6.ar = output:MAXNUM; Q7.ar = output:MAXNUM; /* output.oe = 'b'1; __ only Q0 is setted, others do not output !! */ Q0.oe = 'b'1; Q1.oe = 'b'1; Q2.oe = 'b'1; Q3.oe = 'b'1; Q4.oe = 'b'1; Q5.oe = 'b'1; Q6.oe = 'b'1; Q7.oe = 'b'1; output.sp = 'b'0; /* Q8.ar = output:10; Q8.sp = output:MAXNUM; */


 カウントの出だしの部分をシミュレータで確認した結果が下図です。

シミュレータでのカウント動作の確認結果


 ライターはTL866II pulsを使い、実際にGAL22V10Dに書き込んで動作確認した結果が下図です。
 上記のソースにも書いてあるように20MHzのクロックを入力して、38400bps(カウンタのレジスタ数を8個としたことから決めた速度)の3倍の8.68[usec]が目標周期なのでほぼ目標通りの値になっています。

分周した波形(Q7)


 しか~し、
  • CUPLのNODEが使えない
     NODE宣言でPINに出さないレジスタを宣言するとエラーになるのでGAL22V10ではNODE機能が使えないようですorz
     そのため、カウンターで使用しているレジスタを全てPINに出力する必要があり、出力PINが非常に無駄になります。

  • 9個目のレジスタを使うとエラーが発生
     GAL22V10には10個のレジスタがあるのに9個以上使用すると下記のエラーが発生し、コンパイルできませんでした。



 等の理由から、タイマー割込みをGALで生成するのは諦めましたw
 ここは素直に8ピンのPIC(水晶発振用ICも兼ねる)を使う予定です^^


★2020/10/22 追記 {
 上記のG22V10でレジスタが8個までしか使えないと書きましたが、エラーの原因が判りました。
 下図の赤マーク部分に記載があるようにresetは全レジスタで共通になっているので個別に別々の論理式を書くと上記のエラーが発生します。
 同様にsp(SYNCHRONOUS PRESET)も全レジスタで同じ論理式にしないとエラーになります。

GAL22V10ダイアグラム(抜粋)
}


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(1)  コメント(1) 
共通テーマ:趣味・カルチャー