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

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第75回]

●CKCONSOLルーチン

私はどうやらとんでもない思い違いをしていたようです。
謎を解く鍵はこの中(下図)にありました。
皆様、おわかりになりますでしょうか?



というところで、前回は終わりました。
私は、てっきりCKCONSOLルーチンは「ファンクションコール0BH専用のルーチン」だと、思い込んでいました。
そうではなかったのです。
上のコメントには、こう書いてあります。

Check the console during output

そういうことだったのでした。
CKCONSOLルーチンはコンソール出力のときにもコールされていたのです。

こちらがファンクションコール02(コンソール出力)でコールされているOUTCHARルーチンです。
1398行にCALL CKCONSOLがあります。



私は、テストプログラムの中で、ファンクションコール0BHが実行されたときだけ、Ctrl−Sが受け付けられて、そこでポーズする、と思い込んでいたものですから、「時空のゆがみがぁぁ」などと、たわごとをのたもうことになってしまったのでありました。

0000と表示したところで停止したのは、まさにそこでCtrl−Sが受け付けられたから、でした。
次の65を表示する直前で、CKCONSOLルーチンがコールされて、そこでCtrl−Sが検出されてポーズしたのでした。
そのことがおきたのは、テストプログラムFNC0BT2で、WK3の値を表示しようとしているときです。
下のリストで見ますと、アドレス8115のCALL B2HEXDPのところです。

2012/3/26  20:6  fnc0bt2.txt
END=81B2
              ; BDOS function0B test fnc0bt2
              ;2012/3/26
              ;
              	ORG $8100
              	FCALL=$8005
              	CHARBUF=$C707
              	WK1=$8300
              	WK2=$8301
              	WK3=$8302
              ;
8100 0E0B     LOOP:LD C,0B
8102 CD0580   	CALL FCALL
8105 F5       	PUSH AF
8106 3A0083   	LD A,(WK1)
8109 CD7781   	CALL B2HEXDP
810C 3A0183   	LD A,(WK2)
810F CD7781   	CALL B2HEXDP
8112 3A0283   	LD A,(WK3)
8115 CD7781   	CALL B2HEXDP
8118 F1       	POP AF
8119 F5       	PUSH AF
811A CD7781   	CALL B2HEXDP
811D 3A07C7   	LD A,(CHARBUF)
8120 CD7781   	CALL B2HEXDP
8123 F1       	POP AF
8124 B7       	OR A
8125 C22E81   	JP NZ,KEYIN
8128 CD5981   NEXT:CALL SPDP
812B C30081   	JP LOOP
812E 3E2A     KEYIN:LD A,2A;'*'
8130 CD5B81   	CALL ADP
8133 0E01     	LD C,01
8135 CD0580   	CALL FCALL
8138 F5       	PUSH AF
8139 3E3A     	LD A,3A;':'
813B CD5B81   	CALL ADP
813E F1       	POP AF
813F F5       	PUSH AF
8140 CD7781   	CALL B2HEXDP
8143 F1       	POP AF
8144 F5       	PUSH AF
8145 CD5B81   	CALL ADP
8148 F1       	POP AF
8149 FE1A     	CP 1A;^Z
814B C8       	RET Z
814C C32881   	JP NEXT
              ;


アドレス8102のファンクションコール0BHが実行された時点では、まだCtrl−Sは受け付けられてはいませんから、その下のところで実行されたWK1とWK2のコンソール出力の値はともに00です。
そしてその次のWK3の値(この時点ではまだ65のまま)がコンソール出力される直前にCKCONSOLルーチンが実行されて、そのときにCtrl−Sが受け付けられたのでした。
しかし、BIOSがうまく対応できていなかったために、Ctrl−Dが受け付けられず、それが入力コード04としてCHARBUFに入れられただけでリターンしてきてしまいました。
そのあとWK3の値(65)が表示されたのでした。

あれえ?
WK3にはCKCONSOLルーチンの中で、Ctrl−Dの値(04)が入れられたのではないの?

その通りです。
確かにCKCONSOLからリターンしてきたときにはWK3の値は04になっていたはずです。
しかしその直後にコンソール出力された値は、そのときのWK3の値ではなくて、それ以前にアドレス8112のLD A,(WK3)で入れられた値ですから、それはまだ65なのです。

さてWK3の表示ルーチンの中でコールされたCKCONSOLルーチンは、Ctrl−Dを入力文字としてCHARBUFに入れたあと、Aレジスタに01をセットしてリターンしてきます。
しかしファンクションコール0BHと違って、このAレジスタの値はコンソール出力ルーチンの中では参照されることなく捨てられてしまいます。
WK3の表示のあとで表示された00は、その前にアドレス8102でコールしたファンクションコール0BHの結果をここで表示したものですから、その時点ではまだ「入力無し」の00が表示されたのです。

そしてそのあと、アドレス811DでCHARBUFから読み込んでコンソール出力されたのは、その上のWK3出力中にCKCONSOLルーチンが実行されて、そのときにCHARBUFに入れられたコード04だったのでした。

そしてそのあと1桁のスペースが表示されて、またアドレス8100に戻ります。
そのあとは何がおきて、そしてその結果、何が表示されたでしょうか?

[第73回]のログファイルからその部分を取り出して下に示します。

0000650004 0413040104*:04
           ↑ここからが次の表示
最初の04は次にファンクションコール0BHからリターンしてきたあとのWK1の値です。
WK1はそれ以前にCHARBUFに入れられた値ですから04になります。
その次の13はWK2の値です。
これは?

このWK2を理解するためには、もう一度CKCONSOLの動きを理解する必要があります。



1378行でCHARBUFの値をチェックしています。
CHARBUFには04が入っていました。
00ではありませんから、するとそれ以後のルーチンは実行されなくて、CKCON2にジャンプしてしまいます。
そこでAレジスタに1が入れられるだけでリターンしてしまいます。
つまり、このときはWK2、WK3、CHARBUFの値は変更されずに、それ以前にCKCONSOLが実行されたときの値をそのまま保持していたのです。

それが、Ctrl−S入力でポーズし、そしてCtrl−D入力で表示を再開した次に表示されたデータの意味だったのです。

再掲します。
0000650004 0413040104*:04
           ↑ここからが次の表示

WK2には、その前のCKCONSOL実行時に、さきほどの1379行のCALL CONSTのあとでセットされたCtrl−Sの値(13)がそのまま残っていたのでした。
その次のWK3の値も同じ理由から04のままになります。
そしてその次は、ファンクションコール0BHからリターンしてきたときのAレジスタの値ですから、上で説明した通り01になります。
次のCHARBUFの値もその前の内容から変化しませんから04です。
そしてこのCHARBUFの値が、アドレス8135のファンクションコール01の実行で入力文字コードとして読み込まれます。
コード04は文字としては表示されませんから、*:だけが表示されて、文字は表示されていません。
最後に16進では04と表示されます。

うむむ。
やっと。
つじつまが合いました。
やっと、納得です。

やっと納得はできましたが、このままにしておくわけにはいきません。
ちゃんとCtrl−S、Ctrl−Dが機能するようにCP/Mソースを直さなければなりません。
説明がちょっと長くなってしまいましたので、その変更作業につきましては次回に説明することにいたします。

ワンボードマイコンでCP/Mを![第75回]
2012.3.29upload

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