Z80GALの構想(その7)hexローダーでのCP/M-80ブート [Z80]
前々回の記事でタイマ割込みによるシリアル通信を実装し、前回の記事でSDカードのアクセスに必要なSPIインターフェースを実装したので今回はいよいよCP/M-80の移植です。
いままで検討してきたZ80GAL基板は想定通り、Z80:Z84C0020PEG(40PIN)、RAM:UM61512-15(32PIN)、EEPROM:W24C512-45Z(28PIN)、GAL:GAL22V10D(24PIN)、クロック&タイマ:PIC12F683(8PIN)の5チップ構成で仕上がりそうです。
CP/M-80の起動画面が下図です。
hexローダーでCP/M本体とBIOSをロード後、BIOSの先頭(boot)を実行することでCP/Mが起動しています。(^^)/
久々にHI-TECH Cでコンパイルした際の画面です。「-v」オプションで詳細表示指定しています。
しかし、今回のCP/Mの移植はいつもより、少し手間取りました・・ ^^;
他の人の参考になるかもしれないので発生した主要な問題を二つ書いておきます。
以上が、Z80GALへCP/M-80を移植した際に発生した問題の簡単なメモになります。
今回のソフトによるSPIインターフェスでのSDカードのアクセスはできるだけ高速化したつもりですが、Pic24CPMと比較して体感上はSDアクセスが倍以上遅く感じます(^Cでのシステム+ディレクトリ読込みで2秒程度時間が掛かる)。
Pic24CPMでは例えばSDリード時はPICでアクセスしたデータをZ80に引き渡し、更にDMA領域に転送していたので(Z80GALでは直にDMA領域への読込み)もう少し速くなると期待していたのですが・・
CP/Mのメモリサイズも62KBになったのでBlocking/Deblocking処理を追加してSDアクセスを高速化したいと思います。
因みにタイマ割込み処理は34.7us間隔で割込み処理時間は約7us程度(シリアル通信状態にも依存)なので
20MHz x (35 - 7) / 35) = 16MHz
のクロック相当の処理速度です。Pic24CPMのクロックが丁度16MHzなのでASCIIART.BASを並べて実行してみたところ、見た目上はまったく同じ速度でした。
[TOP] [ 前へ ] 連載記事 [ 次へ ]
いままで検討してきたZ80GAL基板は想定通り、Z80:Z84C0020PEG(40PIN)、RAM:UM61512-15(32PIN)、EEPROM:W24C512-45Z(28PIN)、GAL:GAL22V10D(24PIN)、クロック&タイマ:PIC12F683(8PIN)の5チップ構成で仕上がりそうです。
CP/M-80の起動画面が下図です。
hexローダーでCP/M本体とBIOSをロード後、BIOSの先頭(boot)を実行することでCP/Mが起動しています。(^^)/
Z80GALでのCP/M-80起動画面 |
|
久々にHI-TECH Cでコンパイルした際の画面です。「-v」オプションで詳細表示指定しています。
HI-TECH Cでのコンパイル |
|
しかし、今回のCP/Mの移植はいつもより、少し手間取りました・・ ^^;
他の人の参考になるかもしれないので発生した主要な問題を二つ書いておきます。
- M80/L80で作成したCOMファイルの問題
アセンブラ/リンカはMACRO-80(M80/L80)を使っていて、DOS窓でCPMエミュレータで動かしています。生成したcomファイルは開始アドレスを指定してhexファイルに変換後、モニタでZ80GAL内のメモリにダウンロードしています。
開始アドレスを指定できるHEXファイル変換ツールが見当たらなかったので簡易的なツールを自作しました(「Z80GALの構想(その4)簡易モニタの製作」の記事の末尾に追記して公開しました)
今回は割込み処理、SPIインターフェース及びSDカード初期化等もあるので64KBのCP/MではBIOS領域が足りず、CP/Mを62KBサイズにしているのでBIOSは0F200Hから始まります。
COMファイルを生成するために先頭で「ORG 0100H」で宣言後、.phaseステートメントを使って実アドレスを指定しているのですが、.dephaseして、再度.phaseした際に生成されるcomファイルが16バイト欠落する問題が発生しました。
アドレス再指定部分のソースは下記のとおりです。
0020 RBUFSZ EQU 32 FFE0 RBUFMSK EQU NOT (RBUFSZ - 1) F6C0 RBufAd EQU ($ + RBUFSZ -1) AND RBUFMSK .DEPHASE .PHASE RBuFAd F6C0 RBuf: DS RBUFSZ ; ;Drive A B C D .. K L F6E0 drvtbl: dtbl <dpha,dphb,dphc,dphd,dphe,,,,,,,> F6E0 F74B + dw dpha F6E2 F75B + dw dphb
下図が生成されたcomファイルをバイナリエディタで確認した結果です。
comファイル内コードの開始アドレスは0F200Hなので「drvtbl」が04E0H(=0F6E0H-0F200H)に配置されるはずなのに下図のように04D0Hに配置されてしまっています。orz
04C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04D0 4B F7 5B F7 6B F7 7B F7 8B F7 00 00 00 00 00 00 04E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
この問題は下記のようにして回避できました(その他の変更箇所もあるので上記のものとアドレスは異なっています)。
0020 RBUFSZ EQU 32 FFE0 RBUFMSK EQU NOT (RBUFSZ - 1) F6E0 RBufAd EQU ($ + RBUFSZ - 1) AND RBUFMSK ; .DEPHASE ; .PHASE RBuFAd F6D2 DS RBufAd - $ F6E0 RBuf: DS RBUFSZ
今回のディバッグスタイルはブレークなどは使わず、机上ディバッグがメインなのでこの手の問題が発生すると手こずります^^;
- CP/M-80の割込み用スタックの制限
Z80GAL用のBIOSを書き上げてCP/Mを起動するとdirコマンド終了後にwboot内のシステムを読込み処理が走った後ディレクトリセクタの読込みが走る(固まる場合もある)現象が発生しました。
他の動作は問題無いように見え、"dir"だけがおかしな状態です。BIOSのソースをいくら確認してもおかしな箇所は見当たらないので、コンソール入出力を初期に作った割込みを使わないものに変えてみたところ"dir"が正常に動作しました。
割込み処理によるスタックの問題と思いdirコマンド実施時に実行されるであろうBIOS内の「READ」や「CONOUT」等の処理を確認し、「READ」処理内のPUSH BC,DE,HLを削除しても状況は変わりませんでした(CONOUTではPUSHは1つだけ)
タイマ割込み処理ではPUSHは2個(AFとHL)だけでしたが少し遅くなりますがHLをメモリ変数に退避したところ、問題が解消しました。
CCP内でのdirコマンド処理からのBIOSコール時ではなく、dirコマンド処理内自体でスタックが溢れていたようです。
ネット情報をざっと調べましたが、CP/M-80実装時における割込み処理のスタック数についての情報は見当たりませんでした(どこかにあるのかも)。
割込み処理内では"PUSH AF"以外はレジスタをメモリ上の変数に保存するか、スタックを切りなおしてPUSH/POPした方がいいようです。
★追記 2020/11/15 {
"dir *.z"等のようにどのファイルにもヒットしないワイルドカードでのdirコマンドで固まる現象が発生しました。
割込み処理内で引き継いだスタックへの"PUSH"を無くし、スタックを切り直してから"PUSH"することで問題が解消しました。
上の記載では割込み処理内で1段だけはスタックを使用しても問題ないようなことを書きましたが割込み処理内ではスタックを切りなおしてPUSH/POPした方がいいようです("CALL"でスタックを使用する場合も同様)
}
因みにCCPがコマンド内容を処理する際のスタック領域は下記のように8段しか確保されていないようです。
E386 CD66E0 GETBACK CALL RESETDR ;reset previous drive. E389 CD5EDE GETBACK1:CALL CONVFST ;convert first name in (FCB). E38C 3ACEE3 LDA FCB+1 ;if this was just a drive change request, E38F D620 SUI ' ' ;make sure it was valid. E391 21F0E3 LXI H,CHGDRV E394 B6 ORA M E395 C209DE JNZ SYNERR E398 C382DF JMP CMMND1 ;ok, return to command level. ; ; ccp stack area. ; E39B 0000000000 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 E3AB = CCPSTACK:EQU $ ;end of ccp stack area.
以上が、Z80GALへCP/M-80を移植した際に発生した問題の簡単なメモになります。
今回のソフトによるSPIインターフェスでのSDカードのアクセスはできるだけ高速化したつもりですが、Pic24CPMと比較して体感上はSDアクセスが倍以上遅く感じます(^Cでのシステム+ディレクトリ読込みで2秒程度時間が掛かる)。
Pic24CPMでは例えばSDリード時はPICでアクセスしたデータをZ80に引き渡し、更にDMA領域に転送していたので(Z80GALでは直にDMA領域への読込み)もう少し速くなると期待していたのですが・・
CP/Mのメモリサイズも62KBになったのでBlocking/Deblocking処理を追加してSDアクセスを高速化したいと思います。
因みにタイマ割込み処理は34.7us間隔で割込み処理時間は約7us程度(シリアル通信状態にも依存)なので
20MHz x (35 - 7) / 35) = 16MHz
のクロック相当の処理速度です。Pic24CPMのクロックが丁度16MHzなのでASCIIART.BASを並べて実行してみたところ、見た目上はまったく同じ速度でした。
[TOP] [ 前へ ] 連載記事 [ 次へ ]