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


PICBASICコンパイラ

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
まるでインタプリタ。でもコンパイラです。超カンタン超シンプルです。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第217回]



●PIC16F627(12)logianaで解析(5)

このところずっとPIC16F627のERASE問題について書いています。
その問題はすでに解決済みなのですが結果に至る混迷の過程を備忘録として残したいと思ってあれこれ迷いに迷ったことなどを書いています。
前回はたまたま11年も前に書いた記事を読み直してみて、随分すごいことをやっていたのだなあと自分のことでありながらちょいと感動してしまいました。
そのころに比べますとこのところの記事の内容などはちょっと薄っぺらいのではないかと思ってしまいます。
つい面倒になって言葉だけで抜けようとしているのではないか。
反省です。
初心に戻ってなるべくしつこく具体的に書くようにしたいと思います。
なんたって備忘録なのでありますから。
しかし。
ああ。
時間が欲しい。

前回は下のように書きました。

詳細は省きますがND80Z3.5を使ってPICKITUから出力される最初のPGCパルスを読んでスタートするプログラムを作って、最初の30msの期間は無視したあと次にPGCパルスが出現するまでの時間をIN命令とレジスタのカウントUPを組み合わせることで測定しました。
その間にカウントされたレジスタ(H、L、B、Cをつないだ32ビットカウンタ)の値を読むことでそのおよその経過時間を測定してみました。
結果は最初のデバイスIDの取得から次のコマンドまでの間に170msほどの空白の期間があることがわかりました。

(上記170msのところの訂正については今回の下のほうに書いてあります)

せっかくND80Z3.5を使ったのでありますから、そこのところをどのようにしたのか読者様の参考にもなりますように書くべきでありました。
まずは現場写真です。

左はPICKITUです。
右はND80Z3.5(試作基板)です。
今は某○国の基板メーカーに発注しておりますので試作でもしっかりレジスト付きです。
というより少量の発注は全て試作扱い(prototype)です。
ND80Z3.5の試作基板を作った当時は国内メーカーに発注していました。
レジスト付きだとその分の製版代がかかりますので試作はもっぱらレジストなしで発注したものです。
調べてみましたら2012年夏の製造基板でした。
なんと12年も前の基板です。
それが今も現役です。
ちょいと自画自賛ですけれどなかなかのものでありましょう。

それで話を戻しまして。
やっていることは簡単なことです。
ND80Z3.5のI/O(82C55)のPA7(どのポートでもよいのですけれど)をPICKITUのPGC端子につなぎGNDを接続します。
PIC16F627は28pinソケットに実装しますが空いている40pinソケットの39pinにもPGCが配線してありますから今回はそれを使います。
あっと。
忘れるところでした。
上の写真のように接続して測定を開始したのですが値が取れません。
確認してみたところPA7の入力が浮き上がって中間電位になっていました。
書き込み開始前はPICKITUのPGC出力はハイインピーダンスではありませんが出力抵抗値がかなり高いようです。
これでは測定できませんからND80Z3.5の82C55の入力回路につけてあるプルアップ抵抗(10KΩ)を外しました。
こういう場合にはプルアップ抵抗は無いほうがよいですねえ。

ハードとしてはそれで準備OKです。
次はプログラムです。
簡単なプログラムですからND80Z3.5のアドレス8000〜に直接マシン語コードを打ち込んで作りました。
下の画面はそれをファイルとして保存したものを再ロードしています。

でもこれじゃあ何をやっているのかわかりませんね。
ND80Z3.5の附属CDROMには便利なツールが入っているのです。
一旦ZB3BASICを終了してMSDOSプロンプト(コマンドプロンプト)に戻ります。

この画面はWindows98SEです。
こういう作業はWindows7などよりも楽なのでいまだにWindows98SEは手放せません。
ZDASプログラムでLGCKND.BINを逆アセンブルしました。
LGCKND.DLSとLGCKND.DTXが作成されました。



LGCKND.DLSを開いてみました。
中身はTXTなのでメモ帳やTeraPadなどで開けます。
うまく開けないときは拡張子をTXTに変更してしまえば開けるようになります。
8000 3E90           LD A,90
8002 D383           OUT (83),A
8004 210000         LD HL,$0000
8007 010000         LD BC,$0000
800A DB80           IN A,(80)
800C E680           AND 80
800E CA0A80         JP Z,$800A
8011 16F0           LD D,F0
8013 CDDF06         CALL $06DF
8016 DB80           IN A,(80)
8018 E680           AND 80
801A C22D80         JP NZ,$802D
801D 0C             INC C
801E C21680         JP NZ,$8016
8021 04             INC B
8022 C21680         JP NZ,$8016
8025 2C             INC L
8026 C21680         JP NZ,$8016
8029 24             INC H
802A C21680         JP NZ,$8016
802D 54             LD D,H
802E 5D             LD E,L
802F 210081         LD HL,$8100
8032 71             LD (HL),C
8033 23             INC HL
8034 70             LD (HL),B
8035 23             INC HL
8036 73             LD (HL),E
8037 23             INC HL
8038 72             LD (HL),D
8039 C33310         JP $1033

これで何をやっているかがわかりやすくなりました。
LGCKND.DTXも開いてみます。
こちらは再アセンブル可能なソースプログラムファイルです。
      ORG $8000
      Z0000=$0000
      Z06DF=$06DF
      Z8100=$8100
      Z1033=$1033
      LD A,90
      OUT (83),A
      LD HL,Z0000
      LD BC,Z0000
Z800A:IN A,(80)
      AND 80
      JP Z,Z800A
      LD D,F0
      CALL Z06DF
Z8016:IN A,(80)
      AND 80
      JP NZ,Z802D
      INC C
      JP NZ,Z8016
      INC B
      JP NZ,Z8016
      INC L
      JP NZ,Z8016
      INC H
      JP NZ,Z8016
Z802D:LD D,H
      LD E,L
      LD HL,Z8100
      LD (HL),C
      INC HL
      LD (HL),B
      INC HL
      LD (HL),E
      INC HL
      LD (HL),D
      JP Z1033

ZDASはZ80逆アセンブラですが、もちろんZ80アセンブラも8080アセンブラもND80Z3.5キットに標準で附属しています。
そのほかにZB3BASICも使えます。
ND80Z3.5は超すぐれもののキットなのです。
以上宣伝でした。

説明を続けます。
スタートしたらPA7入力(PGC)がHになるのを待ちます。
PA7=Hを検出したらDレジスタにF0を入れて06DFのシステムサブルーチンをCALLします。
06DFは125μs×Dの値の期間ウェイトします。
D=F0(240)なので240×125=30000μs(30ms)です。
30msの期間ウェイトすることで最初のデバイスIDの読み込みのところをパスします。
その後はC、B、L、Hの順にインクリメントしながら次にPA7がHになるのを待ちます。
PA7がHになったらそのときのC、B、L、Hの値をアドレス8100〜8103に書いてシステムに戻ります。
下は実行時のログです。
logfile nd80zlog\01250709.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
ndwr2h.bin loaded,from E23F to E535
>/ld lgcknd.bin,8000
loading LGCKND.BIN ...003c(60)bytes loaded,from 8000 to 803B
>ot 90,83
>in 80
00
>jp 8000
>cm 8100
8100 67-
8101 19-
8102 01-
8103 00-
>in 80
00
>jp 8000
>cm 8100
8100 EA-
8101 99-
8102 00-
8103 00-
>in 80
00
>jp 8000
>cm 8100
8100 7A-
8101 9A-
8102 00-
>jp 8000
>cm 8100
8100 1B-
8101 9C-
8102 00-
>jp 8000
>cm 8100
8100 6D-
8101 9A-
8102 00-
>

何回か繰り返し実行しています。
ばらつきがありますが最初の1回以外はLとHは00です。
ざっくりとしたところでBC=9A00として計算をしてみます。
まずCレジスタが1カウントされる時間を求めます。
下のリストの右につけた数値は各命令のクロック数です。
8016 DB80           IN A,(80)    11
8018 E680           AND 80        7
801A C22D80         JP NZ,$802D  10
801D 0C             INC C         4
801E C21680         JP NZ,$8016  14
8021 04             INC B
8022 C21680         JP NZ,$8016

11+7+10+4+14=42クロック
ND80Z3.5のCPUクロックは6MHzなので42/6=7μsになります。
Cレジスタが256カウントされるとBレジスタが1カウントされます。
7×256=1792μsでBレジスタが1カウントされます。
Bレジスタが9A(=154)だとするとそのときの経過時間は1792×154=275968μs(≒276ms)と計算されます。
あれ?
前回はどこを見て書いたのでしょう。
170msは誤記でした。
正しくはおよそ280msです。
やっぱりこうやってしっかりと検証しつつ書くべきでありました。

PICBASICコンパイラ[第217回]
2025.2.11 upload

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