SSブログ
English Version

Z80GALの構想(その13)プリント基板完成 [Z80]

 「Z80GALの構想(その10)回路図とパターン設計」で試作基板の評価結果を反映したプリント基板を発注したことを書きましたが、今回は届いたプリント基板の制作についてメモで残しておきます。回路図やプリントパターン等は前述の記事にアップデート版を書いていますので参照してください。

 今回は前回の評価結果をフィードバックしたので一発で動作しました^^
 今回のZ80GAL基板は拙作のPic24CPMと比較すると使用IC数は多いですが、プリント基板サイズはほぼ同じで処理速度が若干速くなっており、当初の予定通りのコンパクトなZ80シングルボードができました^^

 今回は2020/12/11にSeeedさんに10枚発注して、12/28に届きました。出来上がったプリント基板が下の写真です。

 レジスト色は青にしてみました。

Z08GAL V0.01a プリント基板(トップ面)


 上の写真の中央部の「BankSel」のシルクの'n'が少しかすれています(回路的には影響無し)が、それ以外は問題ない状態でした。
 下の写真のボトム面は特に問題ありませんでした。

Z08GAL V0.01a プリント基板(ボトム面)


 表面実装の部品は爪楊枝で半田ペーストを盛ってから部品を置いてヒートガンで熱して半田付けしています。
 今回は初めてマイクロSDカードを使ってみましたが、コンパクトでいいですね^^

部品実装後のプリント基板(トップ面)


部品実装後のプリント基板(ボトム面)


 CP/M-80を起動したときの画面を貼っておきます。

Z80GALでのCP/M起動画面


 今回使ったGAL22V10Dは非常に使い勝手が良かったのでebayで5個セットx2組のGAL22V10Dを追加注文しましたが全てのチップで書込みでエラー発生しましたorz
 使用しているライタはTL866II Plusです。
 そこで最初に発注した正常動作品の購入実績のあるショップで再注文しましたが、またまた全品エラーでしたorz

 ebayで表示される写真も参考にしながら確認したのですが、写真での判断は難しいですね(写真と同じものが来るとも限らないし)
 少し高くなりますが互換性のあるMicroChip社(旧Atmel製)の現在でもディスコンになっていないATF22V10Cを手配し、配達待ち状態です。

★追記 2021/01/05 {
 注文していたATF22V10Cが届きました。書込みはエラー無しでしたが、パワーオンリセットがうまく働かず、電源ONで自動起動しない現象が発生しました(リセットスイッチ押下で正常に起動)
 リセット部の抵抗を10Kから2733Kに変更してリセット信号の立上りを遅くすることでGAL22V10DとATF22V10Cの両方で正常動作するようになりました。
 「Z80GALの構想(その10)回路図とパターン設計」に記載の回路図も変更済みです。
 また追加注文したGAL22V10D(5個)も届き、久々に書込みOKのものでした。同ショップに5個追加注文しました。
}
★変更 2021/01/06
 抵抗値を27Kから33Kに変更(27Kのチップ抵抗が手持ちで無かったため)

GAL22V10Dでの書込みエラー

★追記 2021/01/07 {
 数種類のSDカードを評価した結果、電源ON時の動作の違いはリセット部の抵抗ではなく、SDカード依存であることが判りました。
 このため、抵抗値を10Kに戻します。
 今回評価したSDカードの写真を記録として貼っておきます。
★追記 2021/01/17
 Z80GALが対応しているSDカードはSDHC(容量が4GB~32GB)なので下の写真の左端のものは対応対象外のSDカードです。

評価したMicroSDカード
}


★追記 2020/12/31 {
 従来からの趣向を変えてCNCを使わずに3Dプリンタのみでケースを作ってみました。
 クリア色のPETGフィラメントを使うことで基板上のLEDが見えるようにし、専用の窓を省きました。
 プリント基板のデータはDesignSparkPcbからエクスポートしたものをDesignSparkMechanicalに取り込んでサイズを合わせました(電源コネクタ等は実物測定して合わせた)

Z80GALケース(CAD)

 ボディー側にはケースキャップを固定するために2カ所にインサートナットを埋め込みました。

Z80GALケース(ボディ)

 ケースの壁が薄いので少しフニャフニャする感じはしますが、まずまずの出来ではないでしょうか?

Z80GALケース
}



★追記 2021/02/03
 ケースの壁厚を少し厚くし、Z80GALの文字を内側に入れました。右上の楕円はLEDが見易くなるように壁厚を薄くしている部分です。

Z80GALケース(ロゴ付き)




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

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

Z80GALの構想(その12)ハードステップモニタ [Z80]

 部品などを整理していたら数十年前に作成したWait信号を用いたZ80をステップ動作させるツールが出てきた・・懐かしい。ラッピング用のソケットで基板に実装されたZ80に接続すると言うなんとも豪快なツールです。

 74LS123でwait信号の発生タイミングを取り、アドレスバス及びデータバスの状態をそれぞれ8個のLEDでモニタできます。ラッピングワイヤで半田付けして配線しています。

Z80ステップモニタ


 下の写真が裏面です。

Z80ステップモニタ(裏面)


 斜めから見るとラッピング用ICソケットの様子が判りますね。

Z80ステップモニタ(斜め)


 Z80GALの基板にマウントした状態が下の写真です。安定してマウントするためにZ80をソケットから少し浮かせています。

Z80GALへマウントした状態


 マウントした状態で電源を入れ、ステップ動作用のスイッチをON/OFFすることでZ80がメモリまたはIOをアクセスする度に停止します。
 Z80GALはクロックが20MHzなのでLS123に接続している抵抗を小さくして調整しました。

ステップ動作


 この状態でステップ動作させるとループ処理のところで繰り返し動作になって抜け出せなくなってしまいます。このツールを用いてハードディバッグするのであれば、ディバッグ用のプログラムを作成し、ステップ動作させれば、それなりにディバッグできるのではないかと思います。

 このような簡易なものでハードディバッグが可能になるのは面白いですね。
 アドレスのコンパレータ等を追加すれば任意のアドレスでのストップ等も可能になりますが、ICEを作りたいわけではないのでこのツールの実装機能あたりが妥当なのかもしれませんね。

 twitterにアップした動画付きコメントを貼っておきます。



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


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

Z80GALの構想(その11)IPLの製作 [Z80]

 前回の「Z80GALの構想(その10)回路図とパターン設計」で書いたようにプリント基板のパターン設計ができたのでseeedさんへ発注しましたが、その後2ヶ所ミスを発見orz
 1つはシルクが2022年になっていました(未来から来た基板w)、あと1つはパターンをカットすれば対応できそうですがプリント基板が届いてから具体的な対処を検討します。

 今回は未作成だったIPLを作ったので書いてみます。IPLを先頭セクタに保存し、リセット時に先頭セクタをメモリに読込み、実行することでCP/Mが立ち上るようになります。
 IPLは1つのセクタ(128バイト)に入れるため、SDカードのブロック読込みはEEPROMからRAMへコピーされたコード内の処理を呼び出すようにしました。
 また、割込み処理の切替えは少し面倒なのでシリアル出力は割込みを使用せずソフトでタイミングを取った専用のものを使用するようにしました。

 短いので全ソースを貼っておきます。

Z80GAL IPL(Initial Program Loader)
;+++++++++++++++++++++++++++++++++++++ ; Z80GAL IPL(Initial Program Loader) ; Ver 0.02 2020/11/29 by skyriver ;+++++++++++++++++++++++++++++++++++++ 8000 IPLENT EQU 08000H ; IPL start address 0080 SECSIZE EQU 128 ; sector size 0200 SDBLKSZ EQU 512 ; SD card block size 0004 SECBLK EQU (SDBLKSZ / SECSIZE) ; sec par block 003E MSIZE EQU 62 ; CP/M memory size A800 BIAS EQU (MSIZE-20) * 1024 DC00 CCP EQU 3400H + BIAS ; CCP start address E406 BDOS EQU CCP + 806H ; BDOS start address F200 BIOS EQU CCP + 1600H ; BIOD start address F200 BOOT EQU BIOS FE00 BIOSEND EQU 0FE00H ; BIOS end addtress 0045 RDSEC EQU (BIOSEND - CCP) / SECSIZE + 1 ; add 1sec for IPL 0012 RDBLK EQU (RDSEC + SECBLK -1) / SECBLK 0380 BlkRd EQU 00380H ; SD card block read func HL<-read adrs 0384 SdBlkNo EQU 00384H ; SD block number(big endian) 0386 SdBlkL EQU 00386H ; SD block low number(big endian) 000D CR EQU 13 000A LF EQU 10 ;*** Z80GAL I/O address *** 0080 adBASE EQU 080H ; I/O base address 00E0 adRAM EQU (adBASE + 60H) ; select memory RD D0=1:RAM, 0:ROM 00C0 adSdCs EQU (adBASE + 40H) ; set SD's CS D0=1:active 00A0 AdSd EQU (adBASE + 20H) ; write D0:SDO D1:CLK, read D0:SDI D1:CS 0080 AdSeri EQU (adBASE + 00H) ; serial D0 write:Tx read:Rx 0001 SD_DAT EQU 1 0002 SD_CLK EQU 2 0001 SD_CS EQU 1 .Z80 0000' ASEG ORG IPLENT 8000 F3 IPL: DI 8001 21 8034 LD HL,MSGLD 8004 CD 8054 CALL Puts 8007 21 0000 LD HL,0 800A 22 0384 LD (SdBlkNo),HL 800D 22 0386 LD (SdBlkL),HL 8010 21 DB80 LD HL,CCP - SECSIZE 8013 01 1200 LD BC,RDBLK * 256 + 0 ; B:Blk counter, C:Blk No. 8016 79 IPL10: LD A,C 8017 32 0387 LD (SdBlkL + 1),A ; set Block No. 801A 0C INC C 801B CD 0380 CALL BlkRd 801E B7 OR A 801F 20 0B JR NZ,IPLERR 8021 10 F3 DJNZ IPL10 8023 21 8049 LD HL,MSGOK 8026 CD 8054 CALL Puts 8029 C3 F200 JP BOOT 802C 21 804C IPLERR: LD HL,MSGERR 802F CD 8054 CALL Puts 8032 18 FE JR $ 8034 0D 0A 20 43 MSGLD: DB CR,LF," CP/M loading ... ",0 8038 50 2F 4D 20 803C 6C 6F 61 64 8040 69 6E 67 20 8044 2E 2E 2E 20 8048 00 8049 6F 6B 00 MSGOK: DB "ok",0 804C 49 50 4C 20 MSGERR: DB "IPL err",0 8050 65 72 72 00 8054 7E Puts: LD A,(HL) 8055 23 INC HL 8056 B7 OR A 8057 C8 RET Z 8058 CD 805D CALL Putc 805B 18 F7 JR Puts ;*** softqare serial *** ; 9600bps 1bit length = 1000000/9600 = 104.17 us ; = (1000000/9600)/(1/20) = 2083.3 states(20MHz) 0823 STIMST EQU 2083 ; (10000/96*20) ; state par serial 1bit 009D STICNT EQU (STIMST-11-4-4-7-8+7-4-12)/13+1 ; serial out ; A <- data 805D B7 Putc: OR A ; 4 clear Cy(start bit) 805E 17 RLA ; 4 805F 0E 0A LD C,10 ; 7 set bit counter 8061 D3 80 Putc10: OUT (AdSeri),A ; 11 8063 1F RRA ; 4 8064 37 SCF ; 4 for stop bit 8065 06 9D LD B,STICNT ; 7 8067 10 FE DJNZ $ ; 13/8 8069 0D DEC C ; 4 806A 20 F5 JR NZ,Putc10 ; 12/7 806C C9 RET ; 10 END
★変更 2020/11/29 Putc処理のコードを短縮

 また、リセット後の立上り処理として、SDカードを挿している場合はCP/Mを起動し、SDカードが無い場合にはGAMEインタープリタを起動するようにしました。

 更にCP/M起動後にGAMEの世界に戻ったりGAMEからCP/Mを起動できるようにしてみました。下図がリセット後のCP/M起動から切替え操作例のキャプチャです。

CP/MとGAMEの切替え


 CP/Mが動作している状態でEEPROM内コードをRAMにコピー後に、0003Hから実行するとGAMEインタープリタが起動するようにしています。
 CP/MからGAMEへ移行するためには下記のリストのようにROM/RAM切替の影響を受けないメモリの後半(下記の場合は8000H)で動作するプログラムでEEPROMをアクティブにしてコードをRAMにコピー後、0003HへジャンプすることでGAMEインタープリタが立ち上がります。
 また、GAMEが動作している状態では、単に0000HへジャンプするだけでCP/Mが起動します。

CP/MからGAMEインタープリタ起動コマンドのソース
;+++++++++++++++++++++++++++++++++++++++ ; exit from CP/M-80 in Z80GAL ; Ver 0.01 2020/11/27 by skyriver ;+++++++++++++++++++++++++++++++++++++++ ;*** Z80GAL I/O address *** 0080 adBASE EQU 080H ; I/O base address 00E0 adRAM EQU (adBASE + 60H) ; select memory RD D0=1:RAM, 0:ROM 00C0 adSdCs EQU (adBASE + 40H) ; set SD's CS D0=1:active 00A0 AdSd EQU (adBASE + 20H) ; write D0:SDO D1:CLK, read D0:SDI D1:CS 0080 AdSeri EQU (adBASE + 00H) ; serial D0 write:Tx read:Rx 0001 SD_DAT EQU 1 0002 SD_CLK EQU 2 0001 SD_CS EQU 1 4000 CPYSIZE EQU 4000H ; ROM -> RAM copy size 8000 PROGADR EQU 8000H ; program execute address 0003 GOGAME EQU 0003H ; GAME exute entry .Z80 0000' ASEG ORG 0100H 0100 21 010E LD HL,RELPRG 0103 11 8000 LD DE,PROGADR 0106 01 0011 LD BC,ENDAD - EXTCPM 0109 ED B0 LDIR 010B C3 8000 JP PROGADR 010E RELPRG EQU $ .PHASE PROGADR 8000 F3 EXTCPM: DI 8001 AF XOR A 8002 D3 E0 OUT (adRAM),A ; select ROM 8004 21 0000 LD HL,0 8007 54 LD D,H 8008 5D LD E,L 8009 01 4000 LD BC,CPYSIZE 800C ED B0 LDIR 800E C3 0003 JP GOGAME 8011 ENDAD EQU $ END


★追記 2021/01/22
 CP/MからGAMEインタープリタの世界に移行するためには、ROMがアクティブな状態で0003Hから実行すればいいので、上記のGAMEインタープリタ起動コマンドをスリム化しました。

CP/MからGAMEインタープリタ起動コマンド改善版のソース
;+++++++++++++++++++++++++++++++++++++++ ; exit from CP/M-80 in Z80GAL ; Ver 0.02 2021/01/22 by skyriver ;+++++++++++++++++++++++++++++++++++++++ ;*** Z80GAL I/O address *** 0080 adBASE EQU 080H ; I/O base address 00E0 adRAM EQU (adBASE + 60H) ; select memory RD D0=1:RAM, 0:ROM 00C0 adSdCs EQU (adBASE + 40H) ; set SD's CS D0=1:active 00A0 AdSd EQU (adBASE + 20H) ; write D0:SDO D1:CLK, read D0:SDI D1:CS 0080 AdSeri EQU (adBASE + 00H) ; serial D0 write:Tx read:Rx 0001 SD_DAT EQU 1 0002 SD_CLK EQU 2 0001 SD_CS EQU 1 .Z80 0000' ASEG ORG 0100H 0100 21 DB 021H ; ld hl 0101 D3 E0 OUT (adRAM),A 0103 22 0001 LD (0001H),HL 0106 AF XOR A 0107 C3 0001 JP 1 END



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

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

Z80GALの構想(その10)回路図とパターン設計 [Z80]

 Z80を高速(20MHz)で動作させることで、周辺ICの機能をソフトで代行し、チップ数の少ないZ80シングルボードを作ろうと始めた今回の試みですが、CP/Mも快適に動くようになりゴールに近づいてきたので回路図の整理とパターン設計を行ってみました。

 全体の概要を改めてまとめてみると

  1. チップ構成
     当初の予定通り、8ピンのICも含めて5チップ構成でCP/Mが快適に動くようになりました。
     使用したICは次の通りで、全てDIPパッケージのICです。

    1. Z80
       Z84C0020PEG(40PIN)をクロック上限の20MHzで動作させています。
       メモリも下記のように高速なものを使い、wait無しで動作しています。9600bpsの調歩同期式シリアル通信をソフトで実現するために34.7us間隔で割込み処理を実行していることから処理能力は14.516MHz相当になります(今後改善する可能性もある)。
       当然ですが、シリアル入力をバックグラウンドでセンスしなければ(タイマー割込みを禁止すれば)20MHz相当のスピードになります。
      ★変更 2020/12/30
       処理能力を16MHz相当に変更。詳細は「Z80GALの構想(その8)Blocking/Deblockingの実装」を参照してください。

    2. RAM
       UM61512-15(32PIN)を使用しました。ピン数が少し多いですが、64Kx8bitのスタティックRAMでアクセスタイムは15nsと高速です。

    3. EEPROM
       W27C512-45(28PIN)でアクセスタイムが45nsでROMではかなり速い方だと思います。Z80のメモリ空間の後半は常にRAMをアクセスできるようにしているので、EEPROMのサイズは64Kx8bitですがZ80のメモリ空間の前半の32KBにマッピングしています。
       ジャンパーピンの設定によりメモリ空間にマッピングされるのがどちらか(EEPROMの前半か後半か)を選択可能としました。
       メモリライトは常にRAMが対象となり、メモリリードはEEPROMかRAMかをI/Oでコントロールできるようにしています。

    4. GAL
       GAL22V10D(24PIN)を使用しています。詳細は「Z80GALの構想(その2)GALの設計」の記事を参照してください。

    5. クロック発振&タイマー割込み信号生成
       PIC12F683(8PIN)で水晶発振子用バッファとタイマー割込み用のインターバル信号を生成しています。
       発振部分は後段に一段バッファを設けたかったのですがICが追加になってしまうので後段バッファは無しにしています(PIC12F683の内蔵コンパレータをバッファにできないか試みましたが20MHzでは利得が落ちて駄目でした)

  2. ソフトで代行した機能
     調歩同期式シリアル通信(9600bps)をタイマー割込みを使ってバックグラウンドでの受信センスも含めて実現しています。詳細は「Z80GALの構想(その5)タイマ割込みによるシリアル通信」を参照してください。
     また、SDカードとのインターフェースであるSPIインターフェースをソフトウェアにより実現しています。こちらも詳細は「Z80GALの構想(その6)SPIインターフェースの実装」を参照願います。

  3. 回路図
     今後変更する可能性もありますが、現時点での回路図は下図の通りです。

    ★変更 2021/01/06
     ATF22V10C対応(リセット部の抵抗を10Kから33Kに変更)
    ★変更 2021/02/05
     リセット時の動作の違いはSDカード依存だったのでリセット部抵抗を10Kに戻した


  4. パターン設計
     下図が今回設計した基板のパターン図でトップ面とボトム面を重ねて表示したものです。黄色の細い線はグランドの接続を示していて、グランドをベタパターン化した際に接続されます(接続されない場合はviaを打つ)。

    トップとボトムのパターン(ベタグランド化前)

     トップ面のグランドをベタパターン化したものが下図です。
     今回はMicroSDカードを使って小型化を図りました。SDカードコネクタは秋月さんから購入したヒロセ・マイクロSDカードコネクタを使用しています。
     11ピン~14ピン(周囲の淵にあるピン)は未使用ですが強度を高めるために周りをベタパターン化しました。

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

     下図がボトム面のパターンです。トップ面もそうですが今回はチップ数が多いので結構混雑度の高いパターンになっています。

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


★追記 2020/12/11 {
 試作基板評価結果を反映して回路図とパターン図をアップデートしました。


 【主な変更点】
  • Versionを0.01aに変更
  • microSDの配線を修正
  • R7を10Kから1Kに修正
  • シルクの日付を修正
  • ダイオードの極性が判り易いシルクに変更
  • ダイオードを1種類に統一


試作基板(Ver0.01)

}


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

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

Z80GALの構想(その9)簡易モニタの製作(その2)ブレーク機能の実装 [Z80]

 「Z80GALの構想(その4)簡易モニタの製作」の記事で書いたように今回はZ80GALに移植したGAME言語を使って作成した簡易モニタを使ってプログラムをダウンロードしディバッグを行いました。
 始めからブレーク機能を実装してディバッグに使えば良かったようなものですが、ブレーク機能無しでも今回の開発作業は問題ないと考えていました。
 今回のプログラム開発で残りはIPLくらいしかありませんが、実装方法を考えるのが面白そうだったのでブレーク機能を追加してみました。

 まずはモニタにおけるテスト対象プログラム実行時に期待する機能として、RET命令でモニタに戻ってきた際のレジスタの値などを確認する使い方と、ブレークポイントを設定して実行プログラムがブレークポイントに到達した時点でのレジスタ内容などを確認したい場合の二通りあるのではないかと思います。

 また、いずれの場合もプログラム実行前にはレジスタの値を事前に設定したいものです。

 今回は上記の2つの使い方に対応できるようにしました。それぞれの機能について以下に概要を説明します。

  1. 実行プログラムリターン時のレジスタ確認機能
     事前に任意のレジスタの値を設定して指定した番地からプログラムを実行し、RET命令でモニタに戻ってくる。
     この場合にスタック上にはモニタへの戻り値を積んたうえで対象プログラムを実行します。
     対象プログラムから戻ってきたら、その時点のレジスタを保存し、確認できるようにします。この戻り時の処理は次に述べるブレーク機能と同じ処理になります。
     試験プログラムの実行方法としては「Gaaaa」になります(aaaaは開始アドレス)。

  2. ブレーク機能
     試験対象プログラムの複数個所にブレークポイント(今回はRST 30H(F7H)を使用)を設定後、プログラムを実行し、ブレークポイントに達した時点でモニタに戻し、レジスタ内容の確認などができるようにする。
     今回はブレークポイントを5個まで設定可能で、ブレークした時点で置き換えたF7Hのコードを元のコードに戻す(ブレークポイントを自動的にクリアする)ことで継続して試験プログラムを実行できるようにしました。
     試験プログラムの実行方法はPC(プログラムカウンタ)に実行アドレスを設定後、「G」コマンドで試験対象プログラムを実行します。


 下記のサンプルプログラムを用いて、今回追加した機能についての概要を書いてみます。

使用したサンプルプログラム
  8000    32 800F	LD	(800FH),A
  8003    3E 55  	LD	A,55H
  8005    06 11  	LD	B,11H
  8007    CD 8010	CALL	8010H
  800A    D9     	EXX
  800B    C9     	RET
  800C    00     	NOP
  800D    00     	NOP
  800E    00     	NOP
  800F    00     	NOP
  8010    0E 22  	LD	C,22H
  8012    21 1234	LD	HL,1234H
  8015    C9     	RET


 文字でいろいろ書くよりも操作例を示した方が判り易いと思います。
 ブレークを設定後に最初だけ「Gxxxx」コマンドで対象プログラムを実行し、ブレーク後は「G」コマンドで継続して実行しています。
 最後にRET命令によりモニタに戻ってきますが、この場合、PCの値が不明(ステップ動作すれば判るようになるがそのためには命令長情報が必要になる)なのでPCの表示値は実行開始のアドレス値を表示するようにしました。

 また、今回追加したレジスタ管理機能とブレーク設定/解除機能はいずれもマルチステートメント対応にしているで複数命令を一度に(場合によってはコピペで)実行可能です。

モニタでのブレーク操作例(水色:入力部)
]h *DUMP: D[aaaa[,aaaa]] *FILL : Faaaa,aaaa,dd *GO : G[aaaa] *SET : S[aaaa[,dd]] *IN : Iaa *OUT : Oaa,dd *Reg : X[reg[dddd]] *Break: B[Sn[,aaaa]|Cn|L] n=0..4 READ: R WRITE: Waaaa,aaaa QUIT: Q HELP : H *:can use multi statement separated with ':' command set:= exec:! display:? ]=d8000,801f ]? d8000,801f ]! 8000 : 32 0F 80 3E 55 06 11 CD - 10 80 D9 C9 00 00 00 00 2..>U... - ........ 8010 : 0E 22 21 34 12 C9 00 00 - 00 00 00 00 00 00 00 00 ."!4.... - ........ ]bs,8003:bs1,8007:bs2,8012 adr0:8003 adr1:8007 adr2:8012 ]bs3 adr3:800a ]bl adr0:8003(3E) adr1:8007(CD) adr2:8012(21) adr3:800A(D9) ]! 8000 : 32 0F 80 F7 55 06 11 F7 - 10 80 F7 C9 00 00 00 00 2...U... - ........ 8010 : 0E 22 F7 34 12 C9 00 00 - 00 00 00 00 00 00 00 00 .".4.... - ........ ]xa --.-.--- AF=0000:aa00 ]x --.-.--- AF=AA00 BC=0000 DE=0000 HL=0000 PC=8000 SP=0340 --.-.--- AF'0000 BC'0000 DE'0000 HL'0000 IX=0000 IY=0000 ]g8000 G:8000 at adr0 --.-.--- AF=AA00 BC=0000 DE=0000 HL=0000 PC=8003 SP=033C --.-.--- AF'0000 BC'0000 DE'0000 HL'0000 IX=0000 IY=0000 ]! 8000 : 32 0F 80 3E 55 06 11 F7 - 10 80 F7 C9 00 00 00 AA 2..>U... - ........ 8010 : 0E 22 F7 34 12 C9 00 00 - 00 00 00 00 00 00 00 00 .".4.... - ........ ]bl adr1:8007(CD) adr2:8012(21) adr3:800A(D9) ]g G:8003 at adr1 --.-.--- AF=5500 BC=1100 DE=0000 HL=0000 PC=8007 SP=033C --.-.--- AF'0000 BC'0000 DE'0000 HL'0000 IX=0000 IY=0000 ]g G:8007 at adr2 --.-.--- AF=5500 BC=1122 DE=0000 HL=0000 PC=8012 SP=033A --.-.--- AF'0000 BC'0000 DE'0000 HL'0000 IX=0000 IY=0000 ]g G:8012 at adr3 --.-.--- AF=5500 BC=1122 DE=0000 HL=1234 PC=800A SP=033C --.-.--- AF'0000 BC'0000 DE'0000 HL'0000 IX=0000 IY=0000 ]! 8000 : 32 0F 80 3E 55 06 11 CD - 10 80 D9 C9 00 00 00 AA 2..>U... - ........ 8010 : 0E 22 21 34 12 C9 00 00 - 00 00 00 00 00 00 00 00 ."!4.... - ........ ]g G:800A --.-.--- AF=5500 BC=0000 DE=0000 HL=0000 PC=8000 SP=0340 --.-.--- AF'0000 BC'1122 DE'0000 HL'1234 IX=0000 IY=0000 ]■

★変更 2011/11/22 操作例をアップデート

 このような機能はGAME言語だけでは記述できないので上記の二通りの実行機能(GO:がブレーク用、GOxx:がRET時レジスタ確認用の実行開始モジュール)とモニタへリターン時のレジスタ格納処理(RSTENT:)をアセンブラで記述しました。
 先頭のジャンプ命令とワークメモリアドレスはGAME言語とのインターフェース用です。

ブレーク処理用のアセンブラ記述部分(Z80アセンブラ)
ORG HEXST 0200 C3 0283 RSTJMP: JP RSTENT 0203 C3 02A6 enGO: JP GO 0206 C3 02C7 enGOxx: JP GOXX 0209 00 DB 0 020A 02ED RegWrk: DW SavAFb  ~~ 途中省略 !! Omit the middle!! ;+++++++++++++++++++++++++++++++++++ ; RST break test ; 2020/11/17 by skyriver ;+++++++++++++++++++++++++++++++++++ 0283 22 02FF RSTENT: LD (SavHL),HL 0286 E1 POP HL 0287 2B DEC HL 0288 22 0301 LD (SavPC),HL 028B ED 73 0303 LD (SavSP),SP 028F F3 DI 0290 31 02FF LD SP,SavHL 0293 D5 PUSH DE 0294 C5 PUSH BC 0295 F5 PUSH AF 0296 FD E5 PUSH IY 0298 DD E5 PUSH IX 029A D9 EXX 029B E5 PUSH HL 029C D5 PUSH DE 029D C5 PUSH BC 029E 08 EX AF,AF' 029F F5 PUSH AF 02A0 FB EI 02A1 ED 7B 0305 LD SP,(SavGSP) 02A5 C9 RET 02A6 ED 73 0305 GO: LD (SavGSP),SP 02AA F3 DI 02AB 31 02ED LD SP,SavAFb 02AE F1 POP AF 02AF C1 POP BC 02B0 D1 POP DE 02B1 E1 POP HL 02B2 08 EX AF,AF' 02B3 D9 EXX 02B4 DD E1 POP IX 02B6 FD E1 POP IY 02B8 F1 POP AF 02B9 C1 POP BC 02BA D1 POP DE 02BB E1 POP HL 02BC E1 POP HL ; PC 02BD FB EI 02BE ED 7B 0303 LD SP,(SavSP) 02C2 E5 PUSH HL 02C3 2A 02FF LD HL,(SavHL) 02C6 C9 RET ; Gxxxx command ; SavPC <- xxxx 02C7 ED 73 0305 GOxx: LD (SavGSP),SP 02CB F3 DI 02CC 31 02ED LD SP,SavAFb 02CF F1 POP AF 02D0 C1 POP BC 02D1 D1 POP DE 02D2 E1 POP HL 02D3 08 EX AF,AF' 02D4 D9 EXX 02D5 DD E1 POP IX 02D7 FD E1 POP IY 02D9 F1 POP AF 02DA C1 POP BC 02DB D1 POP DE 02DC FB EI 02DD ED 7B 0303 LD SP,(SavSP) 02E1 21 0283 LD HL,RSTENT 02E4 E5 PUSH HL 02E5 2A 0301 LD HL,(SavPC) 02E8 E5 PUSH HL 02E9 2A 02FF LD HL,(SavHL) 02EC C9 RET 02ED SavAFb: DS 2 ; 0 02EF SavBCb: DS 2 ; 1 02F1 SavDEb: DS 2 ; 2 02F3 SavHLb: DS 2 ; 3 02F5 SavIX: DS 2 ; 4 02F7 SavIY: DS 2 ; 5 02F9 SavAF: DS 2 ; 6 02FB SavBC: DS 2 ; 7 02FD SavDE: DS 2 ; 8 02FF SavHL: DS 2 ; 9 0301 SavPC: DS 2 ;10 0303 0340 SavSP: DW PRGST ; save SP 0305 SavGSP: DS 2 ; GAME's SP


 下のリストが今回機能追加したGAME言語のモニタ(Gamon)のソースです。GAME言語を移植できる環境があるのであれば、モニタの移植も容易だと思います。

Gamon(Game Monitor)ソース(GAME言語)
1' simple monitor(Gamon) V003a 2020/11/19 by skyriver 10 #=10000 100'*** init 110 M=&+1 120 M:1)=$DB M:3)=$32 M(2)=M M:6)=$C9 130 M:7)=$3E M:9)=$D3 M:11)=$C9 140 M:12)=$3E M:14)=$E6 M:15)=$0F M(8)=$3200 M(9)=M M:20)=$C9 150 M:21)=$3E M:23)=$0F M(12)=$0F0F M(13)=$320F M(14)=M M:30)=$C9 160 W=M+31 B=W+20 I=0,9 W(I)=0 @=I+1 162 Y=B+256 164 R=$30 R:0)=$C3 R=R+1 R(0)=$200 R=$20A R=R(0) 170 /"** Gamon(Game Monitor) V0.03a 2020/11/19 by skyriver H:Help **"// 180 ] 200'*** get line 210 P=B Q=B $=Z 220 @ 230 C=$ ;=C<>8 #=260 240 ;=Q=B $=Z #=260 250 Q=Q-1 " " $=8 260 ;=(C=$18)*(Q>B) @ $=8 " " $=8 Q=Q-1 @=(Q=B) 262 ;=Q-B>253 $=8 " " $=8 #=280 270 ;=C>=" " Q:0)=C Q=Q+1 280 @=(C=13) 290 ] 300'** Getc from buf 310 C=0 ;=P<Q C=P:0) P=P+1 ;=(C>="a")*(C<="z") C=C-("a"-"A") 320 ] 350'unpuc 360 ;=C P=P-1 370 ] 400'** Get Hex byte D-> 0..15, -1:NG 410 D=-1 420 !=300 430 ;=(C>="0")*(C<="9") D=C-"0" 440 ;=(C>="A")*(C<="F") D=C-"A"+10 450 ] 500'** Get value A->value F->1:OK,0:NG 510 A=0 F=0 520 @ 530 !=400 ;=D>=0 A=16*A+D F=1 540 @=(D=-1) 550 ] 600'** PutHex byte D<-data,G<-sum 610 M:22)=D >=M+21 M:13)=M:0) >=M+12 620 M:13)=M:0) >=M+12 C=M:0) 630 C=C+"0" ;=C>"9" C=C+"A"-"0"-10 640 $=C 650 M:13)=D >=M+12 C=M:0) 660 C=C+"0" ;=C>"9" C=C+"A"-"0"-10 670 $=C G=G+D 680 ] 710 J=R-U*2+31 I=0,V $=M:J) $=M:J+1) ":" ??=U(0) " " U=U+2 J=J+2 @=I+1 720 ] 800'** Dsp reg 802 ;=U=0 !=880 "AF'" 803 ;=U=1 "BC'" 804 ;=U=2 "DE'" 805 ;=U=3 "HL'" 806 ;=U=4 "IX=" 807 ;=U=5 "IY=" 808 ;=U=6 !=880 "AF=" 809 ;=U=7 "BC=" 810 ;=U=8 "DE=" 811 ;=U=9 "HL=" 812 ;=U=10 "PC=" 813 ;=U=11 "SP=" 820 ??=R(U) 830 ] 880 M:13)=R(U) 882 M:15)=$80 >=M+12 T="-" ;=M:0) T="S" 884 $=T M:15)=$40 >=M+12 T="-" ;=M:0) T="Z" 886 $=T "." M:15)=$10 >=M+12 T="-" ;=M:0) T="H" 888 $=T "." M:15)=$04 >=M+12 T="-" ;=M:0) T="P" 890 $=T M:15)=2 >=M+12 T="-" ;=M:0) T="N" 892 $=T M:15)=1 >=M+12 T="-" ;=M:0) T="C" 894 $=T " " M:15)=$F 896 ] 1000'** dump 1010 ;=P<Q !=500 S=A 1020 U=S M:13)=S >=M+12 S=S-M:0) 1030 E=U+$7F ;=P<Q !=500 ;=A>S E=A 1040 @ ??=S " :" 1050 I=0,15 1060 " " 1070 ;=(S+I>E)+(S+I<U) " " #=1090 1080 ?$=S:I) 1090 ;=I=7 " -" 1100 @=I+1 1110 " " 1120 I=0,15 1130 T=S:I) ;=(T<" ")+(T>"z") T="." 1140 ;=S+I<U T=" " 1150 $=T ;=I=7 " - " 1160 ;=S+I>=E I=15 1170 @=I+1 1180 / S=S+I 1190 @=(S>E) 1200 S=E+1 1210 ] 2000'** Set Memory 2010 ;=P<Q !=500 S=A 2012 ;=P<Q !=500 ;=F ??=S " " ?$=S:0) S:0)=A " - " ?$=A / #=2100 2020 @ 2030 ??=S " " ?$=S:0) " -" 2040 Z=" " !=200 / 2050 ;=P=Q S=S+1 F=1 #=2090 2060 !=500 2070 ;=F S:0)=A S=S+1 2080 ;=C="-" S=S-1 F=1 2090 @=(F=0) 2100 ] 3000'** Fill 3010 G=-1 3020 ;=P<Q !=500 S=A ;=P<Q !=500 ;=A>S E=A+1 !=500 ;=F G=A 3030 ;=G=-1 " ?"/ 3040 ;=G>=0 @ S:0)=G S=S+1 @=(S=E) 3050 ] 4000'** Go 4010 F=0 4012 ;=P=Q "G:" ??=R(10) >=$203 !=4200 !=9394 / ] 4020 ;=P<Q !=500 ;=F "G:" ??=A R(10)=A >=$206 !=4200 !=9394 / ] 4030 " ?"/ 4040 ] 4200'** clear BP 4210 T=R(10) 4220 I=0,9 4230 ;=W(I)=T T:0)=W(I+1) W(I)=0 " at adr" ?=I/2 I=9 4240 @=I+2 / 4250 ] 5000'** IN 5010 !=500 ;=F M:2)=A >=M+1 ?$=A " -> " ?$=M:0) / 5020 ] 6000'** OUT 6010 !=500 ;=F S=A !=500 ;=F M:8)=A M:10)=S >=M+7 #=6030 6020 " ?"/ #=6040 6030 ?$=S " <- " ?$=A / 6040 ] 7000'** Help 7010 " *DUMP: D[aaaa[,aaaa]] *FILL : Faaaa,aaaa,dd"/ 7020 " *GO : G[aaaa] *SET : S[aaaa[,dd]]"/ 7030 " *IN : Iaa *OUT : Oaa,dd"/ 7040 " *Reg : X[reg[dddd]] *Break: B[Sn[,aaaa]|Cn|L]" 7042 " n=0..4"/ 7050 " READ: R WRITE: Waaaa,aaaa"/ 7060 " QUIT: Q HELP : H"/ 7070 " *:can use multi statement separated with ':'"/ 7080 " command set:= exec:! display:?"/ 7090 ] 8000'** Write 8010 !=500 ;=F=0 #=8900 8020 S=A !=500 ;=F=0 #=8900 8030 ;=S>A #=8900 8040 @ 8050 G=0 E=32 ;=A-S+1<E E=A-S+1 8060 ":" D=E !=600 D=S/256 !=600 D=S !=600 D=0 !=600 8070 @ D=S:0) S=S+1 E=E-1 !=600 @=(E=0) 8080 D=-G !=600 / 8090 @=(S>A) 8100 ":00000001FF"/ 8110 ] 8900 " ?"/ 8910 ] 9000'** set cmd 9010 Y:0)=Q-P ;=P<Q I=1 @ Y:I)=P:0) I=I+1 P=P+1 @=(P=Q) 9020 ] 9100'** Display cmd 9110 ;=Y:0)>0 " " I=1,Y:0) $=Y:I) @=I+1 / 9120 ] 9200'** exec cmd 9210 P=B+1 Q=P 9220 ;=Y:0)>0 I=1,Y:0) Q:0)=Y:I) Q=Q+1 @=I+1 9230 C=":" 9240 ] 9300'** Xcmd 9312 !=300 9314 ;=(C=0)+(C=":") !=9394 / ] 9316 U=-1 ;=(C>="A")*(C<="B") U=C-"A"+6 9317 ;=C="D" U=8 9318 ;=C="H" U=9 9320 ;=U<0 #=9330 9322 !=300 ;=C="'" U=U-6 #=9324 9323 !=350 9324 #=9370 9330 ;=C<>"I" #=9350 9332 !=300 ;=C="X" U=4 #=9370 9340 ;=C<>"Y" "?"/ ] 9342 U=5 9350 ;=C="P" U=10 9352 ;=C="S" U=11 9360 ;=U<0 "?"/ ] 9370 ;=P<Q !=500 S=A ;=F !=800 ":" ??=A R(U)=A / ] 9372 !=800 Z=":" !=200 !=500 ;=F R(U)=A 9380 !=300 / 9390 ] 9394 U=6,11 " " !=800 @=U+1 / U=0,5 " " !=800 @=U+1 ] 9400'** Break 9410 !=300 ;=C<>"L" #=9420 9412 I=0,9 9414 ;=W(I) " adr" ?=I/2 ":" ??=W(I) "(" ?$=W(I+1) ")" / 9416 @=I+2 !=300 9418 ] 9420 T=C !=500 ;=(A>4)+(A<0) "?"/ ] 9430 ;=T<>"C" #=9450 9432 T=A*2 A=W(T) ;=A W(T)=0 ;=A:0)=$F7 A:0)=W(T+1) ] 9434 "?"/ ] 9450 ;=T<>"S" "?"/ ] 9452 T=A*2 9454 ;=W(T) "?"/ ] 9456 "adr" ?=T/2 ;=P<Q !=500 ":" ??=A #=9458 9457 Z=":" !=200 !=500 ;=F=0 #=9460 9458 / ;=A:0)<>$F7 W(T)=A W(T+1)=A:0) A:0)=$F7 ] 9460 "?"/ 9470 ] 10000'** main 10010 !=100 10020 @ 10030 Z="]" !=200 !=300 / 10040 ;=C="H" !=7000 #=11000 10050 ;=C="R" >=$20C / #=11000 10060 ;=C="W" !=8000 #=11000 10070 ;=C="=" !=9000 #=11000 10080 ;=C="?" !=9100 #=11000 10090 ;=C="!" !=9200 #=11000 10100 ;=C="G" !=4000 #=11000 10110 ;=C="D" !=1000 #=11000 10120 ;=C="S" !=2000 #=11000 10130 ;=C="F" !=3000 #=11000 10140 ;=C="I" !=5000 #=11000 10150 ;=C="O" !=6000 #=11000 10160 ;=C="X" !=9300 #=11000 10170 ;=C="B" !=9400 #=11000 10180 ;=(C<>"Q")*(C>0) $=C " ??"/ 11000 ;=C=":" !=300 #=10100 11010 @=(C="Q")

★変更 2011/11/19
 Ver0.03a "Gxxxx"と"G"の混在使用を可能にしました。


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

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