目次

Z80ボードによるハードテスト

 手元には、使わなくなったZ80ボードが4つほどあります。

 SRAMは、32kバイトの容量を持つので、ちょっとした処理なら
 簡単に実装できます。このSRAM容量の大きさを使い、ハード
 テストをしてみました。

 CPUであるZ80の能力を最大限に引き出すには、アセンブリ言語
 を利用するのが、最もよいのですが、ファームウエアデバッグ
 が面倒なので、C言語を利用してテストします。

 Z80CPU用コンパイラは、HitechCを持っていますが、SDCCなる
 フリーのCコンパイラが気になっていたので、これを使います。

 Z80CPUボードは、地元の梅澤無線電機が販売しているUECを
 利用します。




 UECに利用されているZ80は、東芝のZ84C015です。  内蔵モジュールは、PIO、CTC、SIOで、Z80ファミリとなって  います。  Z80ファミリのペリフェラルは、モード2割込みを利用できる  ので、AVRやARMのようなマイコンに似たファームウエアを構成  できます。  ハードウエアテストなので、割込みを極力使わない方針をとります。  LEDテスト   制御基板には、個別LEDを載せているので、このLEDの点灯テスト   により、配線が正しいのかをテストします。   LEDテストの定番と言えば、Knight2000のエンブレムにある   左右のランプ点灯。これを考えます。   Cでは、配列が使えるので、7つのパターンを入れて   ループで回せば、Knight2000のエンブレム点灯処理   を実現できます。   ファームウエアを作成する前に、CUIで利用できる   Cコンパイラを使い、動作テストします。   データパターンを作るのが面倒なので、AWKを   使い、16進のパターンを作成します。   AWKスクリプトは、以下としました。 # mkdat.awk   {    result = 0 ;    for ( i = 1 ; i < 9 ; i++ ) {    result *= 2 ;    result += $i;    }    printf("%s => 0x%02x\n",$0,result);   }   データパターンは、次のコードをテキスト   ファイルに格納して対応します。    1 0 0 0 0 0 0 1    0 1 0 0 0 0 1 0    0 0 1 0 0 1 0 0    0 0 0 1 1 0 0 0    0 0 1 0 0 1 0 0    0 1 0 0 0 0 1 0   AWKスクリプトで生成すると、データパターンは   次のようになります。この16進部分を使います。    1 0 0 0 0 0 0 1 => 0x81    0 1 0 0 0 0 1 0 => 0x42    0 0 1 0 0 1 0 0 => 0x24    0 0 0 1 1 0 0 0 => 0x18    0 0 1 0 0 1 0 0 => 0x24    0 1 0 0 0 0 1 0 => 0x42 typedef unsigned char UBYTE ;   UBYTE bpat[6] = {0x81,0x42,0x24,0x18,0x24,0x42};   データをポートBから出力するとして   PIOBに、上で定義済データを出力する   コードを考えます。   シーケンスは、以下とします。
  1. ビットパターンを配列から取得
  2. PIOBにデータ出力
  3. 遅延
  4. 配列に入っているデータ位置を+1
  5. データ位置が6であれば、0に戻す
  6. 1に戻る
  シーケンスは、ステートマシンと同じなので   変数stateを用意して、動作を決めます。  #define LAST 6 state = 0 ; while ( ON ) { /* impress */ PIO_BD = *(bpat+state) ; /* delay */ swait(); /* update */ state++ ; /* judge */ if ( state == LAST ) { state = 0 ; } }   遅延は、関数を用意して実現します。  #define SLAST 256 void swait(void) { UWORD loop ; for ( loop = 0 ; loop < SLAST ; loop++ ) {} }   実機での動作が速すぎる場合、遅延を担当   する関数を何度か動かすように変更します。   I/Oの初期化は、関数を用意して対応します。 void init_pio(void) { /* set control code */ /* set mode 0 (channel A) */ PIO_AC = 0x0f ; /* no interrupt (channel A) */ PIO_AC = 0x03 ; /* set mode 0 (channel B) */ PIO_BC = 0x0f ; /* no interrupt (channel B) */ PIO_BC = 0x03 ; }   SDCCでは、sfr(special function register)という   概念でI/O関係のレジスタをアクセスします。   sfr指定で、次のようにI/O関係レジスタを定義します。 sfr at 0x1C PIO_AD ; sfr at 0x1D PIO_AC ; sfr at 0x1E PIO_BD ; sfr at 0x1F PIO_BC ;   sfr指定は、Cソースコードの中に入れるだけで   よいようです。   Cでは、スタートアップルーチンで様々な設定を   するのが、お約束です。H8やAVRマイコンの使い   勝手に近いコンパイル環境が欲しいので、スタート   アップルーチンは、次のように定義しました。 .globl _main ;.org #0x0000 ld SP,#0x0000 call _main ret   スタックポインタを設定後、即座にCのmain関数   に分岐します。Cのmain関数内部で、I/Oその他を   初期化します。   スタートアップルーチンのmycrt.asmはas-z80を利用し   オブジェクトファイルにして使っています。   ここまでの内容で、LEDをテストするCソースコード   は、次のようにまとめられます。 /* define my system I/O area */ sfr at 0x1C PIO_AD ; sfr at 0x1D PIO_AC ; sfr at 0x1E PIO_BD ; sfr at 0x1F PIO_BC ; /* define data types */ typedef unsigned char UBYTE ; typedef unsigned short UWORD ; typedef signed char SBYTE ; typedef signed short SWORD ; /* define constant values */ #define OFF 0 #define ON OFF+1 #define LAST 6 #define SLAST 256 /* define bit patter */ UBYTE bpat[6] = {0x81,0x42,0x24,0x18,0x24,0x42}; /* function prototype */ void init_pio(void); void swait(void); void main(void) { UBYTE state ; /* initialize PIO */ init_pio(); /* flash LED */ state = 0 ; while ( ON ) { /* impress */ PIO_BD = *(bpat+state) ; /* delay */ swait(); /* update */ state++ ; /* judge */ if ( state == LAST ) { state = 0 ; } } } void init_pio(void) { /* set control code */ /* set mode 0 (channel A) */ PIO_AC = 0x0f ; /* no interrupt (channel A) */ PIO_AC = 0x03 ; /* set mode 0 (channel B) */ PIO_BC = 0x0f ; /* no interrupt (channel B) */ PIO_BC = 0x03 ; } void swait(void) { UWORD loop ; for ( loop = 0 ; loop < SLAST ; loop++ ) {} }   コンパイル、リンクには、次のバッチファイルを   利用しています。   d:\sdcc\bin\sdcc %1.c -mz80 --code-loc 0x0100 --no-std-crt0 -Wlmycrt.o   copy %1.ihx %1.hex   del %1.ihx   ROMライターが受付けるHEXファイルは、拡張子がHEX   なので、ihxからhexコピーで変換しています。 (under construction)
目次

inserted by FC2 system