復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります!
[第89回]
●カレントディスクの仕組み
ファンクションコール0Eをテストした結果として得た結論は、[第86回]に書きましたように、
「ユーザープログラムの中で実行された、ファンクションコール0Eによるカレントドライブの変更は、そのプログラムの中だけ有効で、プログラムが終了するとキャンセルされて、プログラム実行前のカレントドライブに戻る」
というものでした。
それはテストによって確認したことですから確かなことなのですけれど、しかしまだ疑問が残ります。
カレントドライブbヘ当然メモリ上のどこかに保存されているはずです。
しかし、それがユーザープログラム中で変更されても、プログラムが終了すると、「もとの状態に戻ってしまう」、というところが気になります。
おそらく、カレントドライブの記憶場所が複数あって、ユーザープログラム内で使われるもの以外に、システムによって保存されているものが別に存在しているのではないか、と推測されます。
そのあたりが、どうなっているのか、解析してみることにいたします。
●ファンクションコール0Eルーチン
下はファンクションコール0Eの処理プログラム部分です。
ファンクション0Eがコールされると、SETDSK(アドレスD045H)が実行されます。
SETDSKでは、Eレジスタの値を1バイトの記憶場所ACTIVE(アドレスC742H)に書き込んでいます。
どうやらACTIVEがユーザープログラムでのカレントドライブの保存場所のようです。
Eレジスタの値がすでにACTIVEに入っていたとき(つまりEレジスタで指定したドライブbェ現在のカレントドライブであったとき)はそのままリターンします。
それ以外のときは、LOGINDRVにジャンプします。
LOGINDLVはSETDSKの上にあります(アドレスD021H)。
LOGINDRVでは、ACTIVEに入れたドライブb、実際にBIOSコールして選択する(アドレスD02DHのCALL SELECT)とともに、ログインベクタを更新します。
ログインベクタについては、後日説明をいたします。
下はSELECT(アドレスC759H)のエントリ部分です。
ACTIVEから値をCレジスタに入れて、BIOSのSELDSKをコールしています。
やはりACTIVEに入れた値をもとにして、ドライブが選択されているようです。
そうすると、このACTIVEの値が、ユーザープログラムが終了してシステムに戻ってきたときに、ユーザープログラムを実行する前の値に戻される、のではないかと思われます。
果たしてそうなのか、どうなのか。
ユーザプログラムにエントリするときと、ユーザープログラムからシステムにリターンしてきたときに、何が行なわれるのかを、確かめてみることにいたします。
こちらが、まさにその部分です。
アドレスC35CHのCALL TBASEで、8100H(本来は0100H)にロードされたユーザープログラム(トランジェントプログラム)をコールしています。
そして、ユーザープログラムからリターンしてくると、その次のアドレスC35FHから後の処理が行なわれます。
CALL TBASEの直前にCALL SETCDRVがあります。
’reset current drive’というコメントがついています。
ここでカレントドライブに関する何かが行なわれているようです。
そしてユーザープログラムからリターンしてきた後に実行される部分には、CALL MOVCDとCALL DSKSELがあります。
ここでもカレントドライブに関する何かが行なわれているようです。
下はSETCDRVとMOVECDルーチンです。
SETCDRV(set current driveの略だと思われます)では、1バイトの記憶場所CDRIVE(アドレスC3EFH)の値の上位4ビットをユーザーコードにした上でTDRIVE(アドレス8004H。本来は0004H)に入れています。
ここでまた新たな記憶場所CDRIVE(current driveの略か)とTDRIVE(transient driveの略か)が登場しました。
ユーザープログラムから戻ってきたあとで実行されるMOVECD(move current driveか)でも、CDRIVEからTDRIVEに値が移されています。ここではユーザーコードは加えられません。
あれ?
ACTIVEは出てきませんねぇ?
MOVECDの後ではDSKSELが実行されています。
それではDSKSELは?
ということで、サーチしてみましたら。
ファンクションコール0Eでした。
Aレジスタの値をEレジスタに入れて、Cレジスタに14(0EH)を入れて、システムをコールしています。
Aレジスタには、MOVECDでCDRIVEの値が入れられています。
ファンクションコール0Eは、ページトップでお見せしておりますリストのアドレスD045Hのルーチンです。
これで、ユーザープログラムの終了後にCDRIVEからACTIVEに値がコピーされることがはっきりしました。
しかしいぜんとしてはっきりしていないことがあります。
ユーザープログラム開始前のACTIVEには、いつ、何が入れられるのか?ということと、CDRIVEには、いつ、何がいれられるのか?ということです。
’CDRIVE’で検索をかけてみました。
ここはCCP(Console Command Processor)のエントリ部分です。
ここでCレジスタの値がCDRIVEに入れられています(このCレジスタにつきましては[第83回]で説明をしています)。
そして、その後DSKSELをコールしています。
おお。
DSKSELではありませんか。
DSKSELはさきほど説明をいたしました。
ファンクションコール0Eです。
これでやっとつながりました。
CALL DSKSEL
のすぐ上で
LD (CDRIVE),A
が実行されていますから、
ここで(CCPのエントリ直後に)、CDRIVEとACTIVEにCレジスタから同じ値が入れられています。
実はこのほかにもCDRIVEに値が入れられているところがあります。
ここは、上のリストのすぐ下、続きの部分です。
なんだかややこしいことをやっているようですが、CCPにエントリして、a>またはb>などと表示して、コマンド入力を受け付けている部分です。
GETDSKをコールしたあと、Aレジスタの値をCDRIVEに入れています。
それでは、GETDSKは?
といいますと。
こちらがGETDSKです。
これは、ファンクションコール25(19H)です。
ファンクションコール19Hはログインディスク(カレントディスク)のナンバーを取得するファンクションです。
ファンクションコール19Hの処理ルーチンはこちらです。
ここでは、ACTIVEからAレジスタに値を入れています。
むむ。
そういうことになりますと。
ここまでの検討の過程では、CDRIVEがもとになっていて、そこからADRIVEに値が移されるという仮定を立てていたのですが、必ずしもそういうことではなくて、逆にACTIVEからCDRIVEへのコピーも行なわれるようです。
このあたりの考え方は、ちょっと不統一な気がしますが、そのようにしているのには何か意味があるのかも知れません。
CDRIVEに値が入れられているところはもう1箇所ありました。
UNKNOWNというルーチンの中にあります。
このUNKNOWNとは何ぞや?
ということになりますが、それを説明しようとしますと、またあちこち行ったり来たりしなければなりません。
とにかく滅多矢鱈あちこち複雑に入り組んでいます。
もう少しすっきり整理できなかったものか、と思います。
ま。自分のことを棚に上げておいて他人を批判することはできません。
えてして大きなプログラムはそういうことになりがちです。
他人が見ると、どこがどうなっているのか、さっぱりわからないなどということになります(自分が見てもわからなかったりして)。
そういうことですので、ここに至る検索の過程は省略することにいたしまして、ここは結果のみを申し上げますと、UNKNOWNというのは、コンソール入力されたユーザーコマンドを解析するルーチンです。
UNKNOWNつまり未知のコマンドです。
ここに来る前の段階で、コンソール入力された文字列がチェックされていて、先頭にA〜Z(a〜zはA〜Zに変換されています)の1文字+’:’があると、そのA〜Zの文字コード(41H〜5AH)を01H〜1AHに変換した値がCHGDRVに入れられます。
そのあとに続く文字列が無い(つまり○:のみが入力された)場合には、CHGDRVの値−1がドライブbニしてCDRIVEに入れられます。
おお。
ここはたとえば、
a>b:
というように入力したときの処理のようです。
そしてこの後でも、上で説明しましたMOVECDとDSKSELがコールされています。
以上をまとめてみますと、つぎのようになるかと思います。
1)CDRIVEがカレントドライブb保持している
2)CCPにエントリした時にはCレジスタの値がCDRIVEに入れられる。
3)アルファベット+’:’のみを入力してカレントドライブを変更したときは、新しいドライブbェCDRIVEに入れられる
4)ファンクションコール0EはACTIVEを書き換える
5)上記2)および3)では同時にファンクションコール0Eが実行されて、ACTIVEにも同じドライブbェ入れられる
6)ユーザプログラム終了後はファンクションコール0Eが実行され、そこでCDRIVEの値がACTIVEにコピーされる
7)TDRIVE(アドレス8004H。本来は0004H)にはユーザーa{CDRIVEが反映される
8)おそらくファイル操作時のカレントディスクとしてはACTIVEが参照される(GETDSK参照)
1)については、逆にACTIVEからCDRIVEにコピーが行なわれているところもありますので、ちょっと疑問も残りますが、大筋では上のような結論でよいか、と思います。
いやあ。
人様がお書きになったプログラムを解析するのは、本当に疲れます。
ワンボードマイコンでCP/Mを![第89回]
2012.4.12upload
前へ
次へ
ホームページトップへ戻る