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

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

[第74回]

●ファンクションコール0BHの悩ましい振舞い

本日もちょっとわかりにくいお話になってしまいそうです。
前回、テストプログラムの実行中に[Ctrl][S]を入力し、そのあと[Ctrl][D]を入力したときに表示された650004という数値について、「有り得ない」と書きました。
どういうことかと言いますと。

テストプログラムを実行して、a(コード61)、b(62)、c(63)、d(64)、e(65)と順に入力していきました(コードは16進数表記です)。
そして[Ctrl][S]を入力したところ、0000と表示したところでポーズしました。

む?
おかしなところで停止するなあ…。
と思ったのですけれど。
その通り。
確かにおかしかったのです。

テストプログラムの流れからしますと、
0000650000 (最後に1桁のスペース)
と表示されたあと、プログラムのトップに戻って、そこでファンクションコール0BHが実行されるわけですから、最後のスペースが表示されたあとでCtrl−Sが受け付けられて、そこで入力待ちで停止するはずです。
それが途中の0000まで表示したところで停止してしまうというのは、いかにも不自然です。

まあ、しかし。
画面表示もコンソール入力もUSBを介しておこなっているのでありますから、多少のタイムラグもあるかなあと…。
いや、しかし、おかしいなあ…。
そんなことが、ありかなあ…。

見た目には、スペースで停止するべきところ、おっとっと、とちょいと4文字ほどオーバーランしてから止まったと…(いや。しかし。そんなことがありますかいなあ)。
ま。
しかし、基本的にWindowsはイベントドリブンで動いているのでありますから、厳密にはシーケンシャルに処理が進行するとは限らない…。

とにかく、Ctrl−Sの入力前に表示された0000はWK1、WK2の値で、これは勿論、問題はありません。
あ。
WK2も問題かと…。

問題はその次の65の表示です。
これは前回のCP/Mソースリストで見ていただきますと…。
あ。
戻るのは面倒でありますね。
再掲いたします。



おそらくは1383行のCALL CONINで入力された文字コードのはずですから、Ctrl−Sでポーズしたあとに入力したのは、Ctrl−D(コード04)であるべきはずです。
それなのに、そのあとで表示されたWK3の値はCtrl−D入力前と同じコード65…。

ああ。そうか。
停止したときに、棚上げになっていた、Ctrl−S入力前の表示が再開された結果、多分表示バッファに残っていた文字が表示されたのでありましょう…(おかしいなあ。なにか、しっくりこないなあ)。

で、そのあとの00も、Ctrl−S入力前の、コンソール入力無し情報としての00が表示されたのでありましょう、と…。

しかし、しかし。そのあとのCHARBUFの表示になって、突然そこに04(おそらくCtrl−Dの入力コード)が現れるのでありました。
なんで、ここだけ、Ctrl−Dの入力が反映されてしまうのお?

繰り返し何回か試してみたのですけれど、結果はいずれもほぼ同様でありました(停止位置はあちこち前後するのですが…)。
こういうことになりますと、USBを介して画面表示とコンソール入力を同時に受け持っております、ZB3.exeを疑ってしまいます。

むむ。
表示と入力のタイミングに何かとんでもないずれが発生しているのではあるまいか?
ひょっとすると、そこに時空のゆがみが発生しているのでは…。
むむ。
おそろしいこっちゃあ。

こ、これはなんとか解決して、時空のゆがみを元に戻さなければ…。
で。
目を血走らせて、そこで何がおきているのかを、さらに深く探査したのでありました。

うむむ。
入力と表示の関係で何かがおきているとするならば、それはWindows側で発生しているはず。
ならば、Windows側で表示させるのとは別の方法でモニタすることができれば、そこに何かが見えてくるのでは…。

おお。
そうでありました。
ファンクションコール04がありました。

●ファンクションコール04(パンチ出力)

これはちょいと面倒なので、後回しにするつもりだったファンクションコールです。
しかし、いくらなんでもいまどき紙テープパンチャ出力はありませんから、当然別の媒体への出力です。
ND80ZVにはRS232Cの送受信機能があります。



9pinのDサブコネクタがついています。
ここがRS232Cインターフェース回路部です。

ファンクションコール04には、このRS232C出力をあてることにします。
そのために新たにBIOSに追加を行ないましたが、それをここで紹介しますと、ただでさえ説明が交錯しておりますところが、さらに混乱してしまいますので、BIOSの変更につきましては、のちほど整理して説明することにいたします。

ともかくBIOSの追加変更を行なったあと、テストプログラムの方もファンクションコール04を使って、RS232C送信を行なうように変更をして、FNC0BT3.TXTとして保存しました。
下がそのソースリストです。

; BDOS function0B test fnc0bt3
;2012/3/27
;
        ORG $8100
        FCALL=$8005
        CHARBUF=$C707
        WK1=$8300
        WK2=$8301
        WK3=$8302
;
LOOP:LD C,0B
        CALL FCALL
        PUSH AF
        LD A,(WK1)
        CALL B2HEXDP
        LD A,(WK2)
        CALL B2HEXDP
        LD A,(WK3)
        CALL B2HEXDP
        POP AF
        PUSH AF
        CALL B2HEXDP
        LD A,(CHARBUF)
        CALL B2HEXDP
        POP AF
        OR A
        JP NZ,KEYIN
NEXT:CALL SPDP
        JP LOOP
KEYIN:LD A,2A;'*'
        CALL ADP
        LD C,01
        CALL FCALL
        PUSH AF
        LD A,3A;':'
        CALL ADP
        POP AF
        PUSH AF
        CALL B2HEXDP
        POP AF
        PUSH AF
        CALL ADP
        POP AF
        CP 1A;^Z
        RET Z
        JP NEXT
;
;CL & LF
CRLF:LD A,0D
        CALL ADP
        LD A,0A
        JP ADP
;space disp
SPDP:LD A,20
;A disp
ADP:PUSH BC
        PUSH HL
        LD E,A
        PUSH DE
        LD C,04
        CALL FCALL
        POP DE
        LD C,02
        CALL FCALL
        POP HL
        POP BC
        RET
;HL(bynary 2bytes) to asckii 4bytes & disp
HEX4DP:PUSH BC
        PUSH HL
        CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
        PUSH DE
        EX DE,HL
        CALL DEDP
        POP DE
        CALL DEDP
        POP HL
        POP BC
        RET
;A(binary) to asckii 2bytes HEX & disp
B2HEXDP:PUSH BC
        PUSH HL
        CALL B2HEX2
        CALL DEDP
        POP HL
        POP BC
        RET
;
;DE(asckii 2bytes) disp
DEDP:PUSH DE
        LD E,D
        PUSH DE
        LD C,04
        CALL FCALL
        POP DE
        LD C,02
        CALL FCALL
        POP DE
        PUSH DE
        LD C,04
        CALL FCALL
        POP DE
        LD C,02
        CALL FCALL
        RET
;
;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
B2HEX4:LD A,H
        CALL B2HEX2
        EX DE,HL
        LD A,E
;binary to hex, 1byte data to ascii 2charactors,A to DE
B2HEX2:PUSH AF
        RRCA
        RRCA
        RRCA
        RRCA
        CALL B2HEX1
        LD D,A
        POP AF
        CALL B2HEX1
        LD E,A
        RET
;binary to hex, low 4bit to ascii 1charactor
B2HEX1:AND 0F
        ADD A,30
        CP 3A
        RET C;0-9
        ADD A,07;A-F
        RET
;
STRIN:"in"
        DB 3A;:
        DB 24;$
;

こちらはZASM.COMでアセンブルして作成されたアセンブルリストです。

2012/3/27  15:6  fnc0bt3.txt
END=81C7
              ; BDOS function0B test fnc0bt3
              ;2012/3/27
              ;
                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 CD7E81     CALL B2HEXDP
810C 3A0183     LD A,(WK2)
810F CD7E81     CALL B2HEXDP
8112 3A0283     LD A,(WK3)
8115 CD7E81     CALL B2HEXDP
8118 F1         POP AF
8119 F5         PUSH AF
811A CD7E81     CALL B2HEXDP
811D 3A07C7     LD A,(CHARBUF)
8120 CD7E81     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 CD7E81     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
              ;
              ;CL & LF
814F 3E0D     CRLF:LD A,0D
8151 CD5B81     CALL ADP
8154 3E0A       LD A,0A
8156 C35B81     JP ADP
              ;space disp
8159 3E20     SPDP:LD A,20
              ;A disp
815B C5       ADP:PUSH BC
815C E5         PUSH HL
815D 5F         LD E,A
815E D5         PUSH DE
815F 0E04       LD C,04
8161 CD0580     CALL FCALL
8164 D1         POP DE
8165 0E02       LD C,02
8167 CD0580     CALL FCALL
816A E1         POP HL
816B C1         POP BC
816C C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
816D C5       HEX4DP:PUSH BC
816E E5         PUSH HL
816F CDA581     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
8172 D5         PUSH DE
8173 EB         EX DE,HL
8174 CD8981     CALL DEDP
8177 D1         POP DE
8178 CD8981     CALL DEDP
817B E1         POP HL
817C C1         POP BC
817D C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
817E C5       B2HEXDP:PUSH BC
817F E5         PUSH HL
8180 CDAB81     CALL B2HEX2
8183 CD8981     CALL DEDP
8186 E1         POP HL
8187 C1         POP BC
8188 C9         RET
              ;
              ;DE(asckii 2bytes) disp
8189 D5       DEDP:PUSH DE
818A 5A         LD E,D
818B D5         PUSH DE
818C 0E04       LD C,04
818E CD0580     CALL FCALL
8191 D1         POP DE
8192 0E02       LD C,02
8194 CD0580     CALL FCALL
8197 D1         POP DE
8198 D5         PUSH DE
8199 0E04       LD C,04
819B CD0580     CALL FCALL
819E D1         POP DE
819F 0E02       LD C,02
81A1 CD0580     CALL FCALL
81A4 C9         RET
              ;
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
81A5 7C       B2HEX4:LD A,H
81A6 CDAB81     CALL B2HEX2
81A9 EB         EX DE,HL
81AA 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
81AB F5       B2HEX2:PUSH AF
81AC 0F         RRCA
81AD 0F         RRCA
81AE 0F         RRCA
81AF 0F         RRCA
81B0 CDBA81     CALL B2HEX1
81B3 57         LD D,A
81B4 F1         POP AF
81B5 CDBA81     CALL B2HEX1
81B8 5F         LD E,A
81B9 C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
81BA E60F     B2HEX1:AND 0F
81BC C630       ADD A,30
81BE FE3A       CP 3A
81C0 D8         RET C;0-9
81C1 C607       ADD A,07;A-F
81C3 C9         RET
              ;
81C4 696E     STRIN:"in"
81C6 3A         DB 3A;:
81C7 24               DB 24;$
              ;
ADP          =815B  B2HEX1       =81BA  B2HEX2       =81AB  
B2HEX4       =81A5  B2HEXDP      =817E  CHARBUF      =C707  
CRLF         =814F  DEDP         =8189  FCALL        =8005  
HEX4DP       =816D  KEYIN        =812E  LOOP         =8100  
NEXT         =8128  SPDP         =8159  STRIN        =81C4  
WK1          =8300  WK2          =8301  WK3          =8302  


一見したところファンクションコール04は見当たりません。
今までテストに使ってきましたFNC0BT2と同じように見えます。

実はファンクションコール04は、表示のためのサブルーチンに仕込んであるのです。
アドレス815Fと818C、8199です。
ファンクションコール02(コンソール出力)の前に挿入してあります。
こうすることで、コンソール出力としてUSBで送出されるデータと同じものを、コンソール入力やコンソールステータスチェックに妨げられることなくモニタすることができます。

しかし。
RS232Cで送信するというからには、それを受信する側も用意する必要があります。
別のWindowsパソコンのRS232Cで受信する、という方法もあるのですが、そうするとハードとソフトの準備が必要になります(どのみち何かは準備しなければなりませんが)。
私としては最も手っ取り早い方法として、下のような方法でテストすることにいたしました。



ZBKシリーズのボードのZB28Kをちょうど手元で開発作業用に使っておりましたので、それに232Cレベル変換ボード(9pinDSUB)を接続して、それとND80ZVとを9pinのストレートケーブルで接続することにいたしました。
パソコンはいまだにWindows98SEです。
16ビットのアプリケーションや、8ビットボード用のプログラム開発用には、これが一番使い易いのです。
WindowsXPやWindows7はむしろ使いにくくなります。
ND80ZVとはUSBケーブルで接続をしていますが、ZB28Kとはプリンタケーブルで接続しています。
ZB28KもUSB接続することができるのですが、パラレルポートで接続した方が高速で処理できます。
Windows98がなかなか手放せないというのには、このプリンタポートがソフトウェアで制御できる、というのもその大きな理由のひとつです(最近のパソコンにはプリンタポートそのものがありませんものねえ)。
パソコンが普及するにつれて安価になるのは有り難いことなのですが、便利な機能が次々となくなってしまうのは残念なことです。

こちらは上の図のように接続してテスト中の写真です。



そしてこちらが実際にテストプログラムを実行したときのスクリーンショットです。



右側のDOSプロンプトでCP/Mを走らせています。
左側のDOSプロンプトではZB28KでBASICプログラムを実行させました。
こういうときにBASICは実に簡単で重宝します。
ZB28Kの232Cで受信したデータを表示させています。
そのデータをよく見てみますと…。

全く同じじゃありませんか!
一番下の行の 0000420004 がCtrl−S、Ctrl−Dを入力したときの表示データです。
232CでZB28Kに送られてきたデータも、右側のDOSプロンプト画面に表示されたUSB経由の表示データと全く同じ、という結果になってしまいました。

むむむ。
ということは…。
これは時空のゆがみなどということではなさそうです。
ううう。
すると、考えられることは、ただひとつ。

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



次回、全てが明らかになります。

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

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