復活!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
前へ
次へ
ホームページトップへ戻る