SSブログ
English Version

CP/M用hexローダーの製作 [Z80]

 CP/M-80 用のプログラムをアセンブリ言語で書く場合、パソコン上のエディタを使ってソースを編集したいものです。従来は、パソコンで編集したアセンブラソースを Z80 ボードに XMODEM で転送して動かしていました。
 しかし、パソコン上で CP/M エミュレータを使ってアセンブル&リンクして作成した HEX ファイルを TeraTerm 上にドラッグ&ドロップして実行できたらより効率的です。

 そこで CP/M 上で動作する HEX ローダーを作成してみました。このローダーの機能(特徴)は下記の通りです。
  1. コンソールから入力されるインテル HEX 形式のデータをメモリ上に展開します
  2. ロード完了後にHEX ファイルの先頭行のアドレスにジャンプします(ロードプログラムが自動起動します)
  3. CP/M の標準プログラムである 0100H から始まるものもダウンロードできるようにするために自身のコードを 0080H に移動してから実行します
  4. 高速化のために BIOS の機能を直にコールしています

 CP/M 側でこのローダーを起動後に、普通に作成した HEX ファイルを TeraTerm にドラッグ&ドロップすればロード後に自動的に実行されるので転送作業がかなり楽になりました。

 下記のリンクに公開しました。商用利用以外であれば自由に使用可能とします。
[history]
2023/05/15 Ver 0.03 set 00h to 0080H by skyriver
2023/03/26 Ver 0.02 can break by ^C
2023/03/26 Ver 0.01 published


 ソースも貼っておきます。

CP/M-80 用 HEX ローダー(アセンブラ)
;************************************************ ; HexLoader for CP/M ; Ver0.02 2023/03/26 can break by ^C by skyriver ; Ver0.03 2023/05/15 set 00h to 0080H by skyriver ;************************************************ 0001 WBOOTAD EQU 0001H ; wboot address 0080 PROGST EQU 0080H ; bios service No from wboot 0002 CONIN EQU 2 0003 CONOUT EQU 3 ; BDOS service 0005 BDOS EQU 0005H 0009 PrnStr EQU 9 ; print string 0000' ASEG ORG 0100H 0100 3A 0080 HexLd: LD A,(PROGST) 0103 B7 OR A 0104 28 06 JR Z,EXEC 0106 11 0146 LD DE,HlpMsg 0109 C3 00EB JP Puts 010C 21 0170 EXEC: LD HL,CODE_ST 010F 11 0080 LD DE,PROGST 0112 01 007D LD BC,CODE_EN - CODE_ST 0115 ED B0 LDIR 0117 2A 0001 LD HL,(WBOOTAD) 011A EB EX DE,HL 011B 21 0007 LD HL,3 * CONIN + 1 011E 19 ADD HL,DE 011F 4E LD C,(HL) 0120 23 INC HL 0121 46 LD B,(HL) 0122 ED 43 00F1 LD (CONINA),BC 0126 21 000A LD HL,3 * CONOUT + 1 0129 19 ADD HL,DE 012A 4E LD C,(HL) 012B 23 INC HL 012C 46 LD B,(HL) 012D ED 43 00F5 LD (CONOUTA),BC 0131 C3 0080 JP PROGST 0134 48 65 78 4C HexMsg: DB 'HexLoader Start',13,10,'$' 0138 6F 61 64 65 013C 72 20 53 74 0140 61 72 74 0D 0144 0A 24 0146 48 45 58 4C HlpMsg: DB 'HEXLOAD Ver 0.03 2023/05/15 by skyriver',13,10,'$' 014A 4F 41 44 20 014E 56 65 72 20 0152 30 2E 30 33 0156 20 32 30 32 015A 33 2F 30 35 015E 2F 31 35 20 0162 62 79 20 73 0166 6B 79 72 69 016A 76 65 72 0D 016E 0A 24 0170 CODE_ST EQU $ .phase PROGST 0080 00 NOP ; command parameter length 0081 11 0134 LD DE,HexMsg 0084 CD 00EB CALL Puts 0087 16 00 LD D,0 ; first flag 0089 CD 00F0 LOAD: CALL GETCH 008C FE 03 CP 'C' - 40H 008E CA 0000 JP Z,0 0091 FE 3A CP ':' 0093 20 F4 JR NZ,LOAD 0095 CD 00D5 CALL RDBYTE ; get byte count 0098 47 LD B,A 0099 CD 00E2 CALL RDWORD ; get address 009C 7A LD A,D 009D B7 OR A 009E 20 03 JR NZ,RDTYPE 00A0 16 01 LD D,1 ; clear flag 00A2 E5 PUSH HL ; set execute address 00A3 CD 00D5 RDTYPE: CALL RDBYTE ; get record type 00A6 5F LD E,A ; save type 00A7 FE 01 CP 1 00A9 28 14 JR Z,DSPTYP ; end of data 00AB B7 OR A 00AC 20 0C JR NZ,LdErr ; data record 00AE CD 00D5 RDDATA: CALL RDBYTE 00B1 77 LD (HL),A 00B2 23 INC HL 00B3 10 F9 DJNZ RDDATA 00B5 CD 00BF CALL DSPTYP 00B8 18 CF JR LOAD 00BA 21 00F7 LdErr: LD HL,ErrMsg ; error occur 00BD 18 2C JR Puts 00BF CD 00D5 DSPTYP: CALL RDBYTE ; read check sum 00C2 CD 00F0 CALL GETCH ; read delimitor 00C5 7B LD A,E ; get type 00C6 C6 30 ADD A,'0' 00C8 18 29 JR PUTCH ; read hex nible ; A -> data 00CA CD 00F0 RDNBL: CALL GETCH 00CD D6 30 SUB '0' 00CF FE 0A CP 10 00D1 D8 RET C 00D2 C6 F9 ADD A,10 + '0' - 'A' 00D4 C9 RET ; read byte data ; A -> byte data 00D5 CD 00CA RDBYTE: CALL RDNBL 00D8 07 RLCA 00D9 07 RLCA 00DA 07 RLCA 00DB 07 RLCA 00DC 4F LD C,A 00DD CD 00CA CALL RDNBL 00E0 B1 OR C 00E1 C9 RET ; read hex word ; HL -> data 00E2 CD 00D5 RDWORD: CALL RDBYTE 00E5 67 LD H,A 00E6 CD 00D5 CALL RDBYTE 00E9 6F LD L,A 00EA C9 RET ; display message ; DE <- message address 00EB 0E 09 Puts: LD C,PrnStr 00ED C3 0005 JP BDOS 00F0 C3 GETCH: DB 0C3H 00F1 0000 CONINA: DW 0 00F3 4F PUTCH: LD C,A 00F4 C3 DB 0C3H 00F5 CONOUTA: 00F5 0000 DW 0 00F7 65 72 72 0D ErrMsg: DB 'err',13,10,0 00FB 0A 00 .dephase 01ED CODE_EN EQU $ END Macros: Symbols: 0005 BDOS 01ED CODE_EN 0170 CODE_ST 0002 CONIN 00F1 CONINA 0003 CONOUT 00F5 CONOUTA 00BF DSPTYP 00F7 ERRMSG 010C EXEC 00F0 GETCH 0100 HEXLD 0134 HEXMSG 0146 HLPMSG 00BA LDERR 0089 LOAD 0009 PRNSTR 0080 PROGST 00F3 PUTCH 00EB PUTS 00D5 RDBYTE 00AE RDDATA 00CA RDNBL 00A3 RDTYPE 00E2 RDWORD 0001 WBOOTAD No Fatal error(s)


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

Z80エクステンダの製作 [Z80]

 Z80関連で実機でちょっと実験したい場合に手軽に動かせる環境があると便利です。
 しかし、今まで作成したZ80ボードはバスや信号線をコネクタで出していないのでハードウェアの実験には使い辛いものになっています。

 「超小型Z80マイコン(その12)PCBへの部品実装」の記事で書いた下図の下駄が思いの外便利だったので、この考え方を踏襲した実験用の下駄(エクステンダ)を作成してみようと思います。

Z80 信号測定用の下駄


 実験ではプログラマブルなディバイスがあった方が便利なので GAL22V10 も実装することにします。
 回路は下図のように至って簡単なものでグランドのベタ化は行わず、電源のトラックを切断すれば他の 40 ピンCPUでも流用し易い様にしました。

Z80 エクステンダの回路図


 パターン図が下図で、これ以上無いほど単純なものになっています。

Z80 エクステンダパターン図


 トップ面の3D表示が下図です。Z80に重なっているピンコネクタは実際にはZ80の右隣のピンコネクタと共にボトム面に細ピンヘッダを付けて既存のZ80ボードのCPUソケットに差し込みます。
 各ICの一つのピンに付きピンコネクタが2個あるので、ブレッドボードの様にジャンパー線で信号を繋ぐことができます。実験に必要な追加部品はブレッドボードに付けで本ボードと接続するか、孫基板に必要部品を実装して本エクステンダのピンヘッダに接続します。

 ロジアナでの信号確認も容易なので結構便利なものになるのではないかと思います。

Z80 エクステンダ3D表示(トップ面)


 下図はボトム面の3D表示です。前述のようにボトム面にはZ80のソケットに刺さるように細ピンヘッダを付けます。また、実験で使うであろう3.3Vを生成するレギュレータもボトム面に実装しました。

Z80 エクステンダ3D表示(ボトム面)


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

電動こて先クリーナーの製作(その2)PICでの制御 [PIC]

 今回の回路設計作業の後に判ったことですが、ネットで探してみたら「ぼくのマイコン開発のメモ」と言うブログの「電動コテ先クリーナ FT-720」の記事に白光のコテ作クリーナーを分解した情報が公開されていました。
 これを見ると白光のこて先クリーナーはマイコンを使用せずに光センサーの出力で直にモーターの ON/OFF を制御しているようです。常にLEDが発光しているのでそれなりに消費電流はあるでしょうが外部電源と言うことなので割り切っているみたいです。

 今、開発中のこて先クリーナーは手持ちの PIC(PIC12F683)使って制御してみたいと思います。以降、作業記録の意味合いも込めて実施した作業内容を時系列で記録していますので、内容としてはあまり面白くないかもしれないことを事前にお断りしておきます。


 始めに仕様について簡単に検討してみました。

[仕様概要]
  1. 電源
     ハンディ性を考慮し、単三電池2本で動くようにする。未使用時には極力消費電流を抑えるようにする。
  2. 動作スイッチ
     スイッチを押すことで10分間 wake 状態になる。タイムアップ時には小電力モードに移行する。
  3. こて先検出時の動作
     wake 状態でこて先を検出した際は一定時間(3秒間)ブラシを回転させる。回転中にこて先を検出した場合は3秒タイマーを再設定する。
  4. ブラシの回転停止条件
     上記の3秒タイマがタイムアップした時点でブラシの回転を停止し、上記の wake タイマを再設定する。
  5. こて先センサ
     光学的なセンサを使用する。外来光からの影響を考慮し、手持ちの赤外線リモコン受信モジュール(以降、赤外線受信モジュールと記す)を使用する。


 最初に考えた回路は電源の電池2本からの3V(ニッケル水素電池なら2.4V)で PIC を動かし、5V動作が必須な赤外線受信モジュールのみ5Vで動かす方式にしました。
 昇圧部と赤外線受信モジュール部の回路が下図になります(クリックで回路全体が見えます)。

昇圧と赤外線受信モジュール部分の回路


 最初は省電力化のためにこて先検出する時のみ5Vの昇圧回路(HT7750 使用)を動かすようにしていましたが、後述する問題があったため、最終的には PIC を含めた全体を5V駆動するように変更しています。

 下図は昇圧回路への3V給電をスイッチ制御するトランジスタ回路部分をシミュレータで確認した際のキャプチャです。結果としては問題無く制御できそうです。

昇圧回路への給電制御部


 下図はソフトで生成した 38KHz の矩形波(黄色※1)で赤外線 LED を駆動した際の赤外線受信モジュールの出力信号(紫色)です。出力信号には 200us 程度のディレーがあるので、38KHYz の矩形波は 16 波(421us)出力するようにしました。矩形波出力完了後に赤外線受信モジュールの出力信号をチェックするようにしています。
※1 3.3V 駆動ですが、波形を保存していなかったのでPICが5V動作時の波形を使っています)

赤外線受信モジュールの出力波形例


 下図は 3,3V で動かしている時にこて先を検出し、ブラシの回転モーターをオンした際の波形です。黄色がモーターのマイナス側(=スイッチしているNMOS FETのドレイン側)の電圧で、紫色が赤外線 LED の駆動波形です。右側は拡大したものです。

ブラシ駆動波形(3.3V動作) ブラシ駆動波形の拡大(3,3V動作)


 電源電圧を 3.3V から 2.4V に変更してみると予想していたことではありますが、FET のゲート電圧が足りず、モーターをオンしている時でも FET の抵抗が大きくなり、ドレイン電圧が高くなりモーターが回転しない状態になってしまいました。

ブラシ駆動波形(2.4V動作) ブラシ駆動波形の拡大(2,4V動作)


 今回使用している NMOS FET は手持ちの8ピンの SOP パッケージで2個入りの uPA2753GR でオン抵抗が小さいことから購入したものです。データシートを確認したところやはり4V以上で使用するのが良さそうですね。

NMOS FET のVgs 特性


 また、sleep 時の電流も想定より大きかったので下記の見直しを行いました。
  • 電源電圧 2.4V でモーターが回らない問題対策
     FET のゲートを引ききれないので PIC 自体も5Vで動かすことにした。これに伴い、5V 昇圧回路の ON/OFF 制御を廃止した。

  • 未使用時の電流低減対策
     未使用時は PIC を sleep 状態にしていたが安定化電源での給電で sleep 時にテスタで電流値を測定した結果 12uA 程度であった。安定化電源のマイナス側を外しても電流測定値が 3uA 程度あることが後で判ったので実力値としては 9uA 程度と予測される。
     対策として未使用時は PIC からの制御により電源をオフにすることにした。
     モーター制御用で使っていた NMOS FET は2個入りパッケージなので未使用だった1個を使って電源制御するように回路を変更した。NMOS なので GND 側をスイッチするようにした。

 上記の対策後の回路図が下図になります。中央下側の PL5 Bat に単三電池2本を接続します( A がプラス側)。

対策後の回路


 未使用時の電流値はテスタ(uAレンジ)では測定不可能なほど小さくなりました。ブレッドボード上での動作も問題無かったのでパターン設計を行いました。緑色部分はグランドです。

パターン図(グランドベタ化前)


 グランドベタ化後のトップ面のパターンが下図になります。PIC はリードパッケージの物を使いました。コネクタはサイド型を使用する予定なので基板の淵からのスペースを確保し、説明のシルク印刷文字はコネクタの後方に書いています。

グランドベタ化後のパターン図(トップ面)


 下図がボトム面のパターンです。SMD 部品をボトム面に配置しました。

グランドベタ化後のパターン図(ボトム面)


 トップ面の3D表示が下図になります。右上のセラコンは何故か立方体になっています。

3D表示(トップ面)


 下図がボトム面の3D表示です。中央上部の茶色の立方体は PIC 書込み用のスルホールで部品は実装しません。PIC はリード品を使用するのでソケットから外して直に書き込むこともできます。

3D表示(ボトム面)


 最後に Twitter にアップしたモーター変更後の物を制御している様子を録画した動画付きメッセージを貼っておきます。




[TOP] [ 前へ ] 連載記事一覧 [ 次へ ]
nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

電動こて先クリーナーの製作(その1) [PIC]

 Twitter で半田ごてのこて先クリーナーを見かけ、確かに便利そうだなぁと思い、Amazon で探したところ結構な値段でした。AliExpress(以降、蟻さんと記す) でも探してみましたが安価な物は見つかりませんでした。

白光のこて先クリーナー


 そこで久々に動くものでも作ろうかということで自作することにしました。
 最初に百均で耐熱性がそれなりにありブラシとして使えそうな素材を探したところ、下の写真の天然たわしを見つけましたw

天然たわし


 また、動力源としてモーター内蔵の物を探しましたが、意外に中々ないものですね。おもちゃコーナーでもモーター付きのものはありませんでした。夏であればUSB用扇風機がありそうですが、この時期に見つけられたモーター駆動の百円商品は下の写真のカプチーノミキサーだけでした。

カプチーノミキサー


 天然ブラシの取っ手からブラシ部分を取り外したものが下の写真です。純正のクリーナーの替えブラシは結構な値段ですが、今回制作予定のものは百円で2台分収穫できますw

取り外したブラシ


 最初は動力源としてドローン用の小型モーターを使って実験していましたがパワー不足でした。上記の百均で購入したカプチーノミキサーからモーターを取り出そうとしたところ、手持ちで同じくらいの大きさのモーターが見つかったのでそれで事前実験しています(円形で平らなモーターを蟻さんでも注文しました)

 まずは、可動部分の構造の実験として下図のようなものを3Dプリンタで作成しました。
 ベアリングは手持ちの物(フィラメントホルダ作成時に購入)を使い、動力伝達用のラバーベルトは蟻さんで購入しました。
 ブラシの支え方で少し悩みましたが、ネジ式で幅を調整できるようにしてベアリングに取付けたパーツの溝にブラシの軸を挟むようにしました。

ブラシ回転部分の構造


 うまく回転させるためにはブラシの回転ブレを少なくする必要があります。試行錯誤した結果、ブラシの軸の針金を整形して微調整するという原始的な方式に落ち着きましたw
 Twitter にアップした動画付きメッセージも貼っておきます。



 次回は PIC を使った制御について書く予定です。


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

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