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

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

[第68回]


●ファンクションコール0BH(コンソールステータスチェック)

ファンクションコール0BHはコンソールのステータスをチェックしてキー入力があったかどうかを調べます。
キー入力があればAレジスタに01を入力するとともに、1バイトのキャラクタバッファに、入力されたキーコードを入力してリターンします。
キー入力がなければ、Aレジスタに00を入れてリターンします。

村瀬康治著「応用CP/M」(アスキー出版局)には記述ミスがあります。
同書50ページにファンクションコールを一覧表形式でまとめてありますが、その中のファンクションコール11(0BH)の説明では、「入力ありのときA←FF」とありますが、A←FFではなくて、A←01です。

キャラクタバッファに入れられたキーコードは、ファンクションコール01を実行すると、そのときにAレジスタに入れられます。
実はファンクションコール01は、最初にキャラクタバッファを調べて、そこにキー入力された文字コードが入れられていたら、実際にコンソールにはアクセスしないで、そのキャラクタバッファのキー入力コードをAレジスタに入れてリターンする仕組みになっているのです。

なぜこんな面倒な仕組みにしているのか、ということなのですが、ファンクションコール01だけだと、キー入力があるまで待っていてリターンしてきませんから、プログラムがそこで止まってしまいます。
それでは困る場合もあることを考えて、この仕組みがあるのでは、と思います。
ファンクションコール0BHとファンクションコール01を組み合わせることで、BASICのINKEY$のような機能になります。

しかし、その用途にはダイレクトコンソール入出力(ファンクションコール06)がありますから、そちらを使ったほうが簡単なのに、と思ってしまいます。

ファンクションコール0BHは、ただキー入力の有無をチェックするだけにも使える(それに何の意味があるか疑問ですが)、とも思えるのですが、上で説明しましたように、ただキー入力の有無をチェックするだけではなくて、キー入力があったときには、あらためてコンソール入力を行ない、実際にキー入力コードをキャラクタバッファに入力してしまいます。

このキャラクタバッファに入れられた文字コードはファンクションコール01を実行するまで、そこに残ります。
もしファンクションコール01を実行しないままプログラムを終了すると、プロンプトマーク(>)が表示された直後に、そのコードがコマンドの一部として読み込まれて表示されてしまいます。
ちょいと面倒で厄介なファンクションコールです。

まあ、でも、一通りはファンクションコールについて検証をするつもりで作業をしておりますので、今回はファンクションコール0Bについて、テストをしてみることにしたのですが…。
やっぱりちょいと厄介なファンクションコールでした。

テストプログラムのソースリストです。

; BDOS function0B test
;2012/3/22
;
        ORG $8100
        FCALL=$8005
        CHARBUF=$C70E
;
LOOP:LD C,0B
        CALL FCALL
        PUSH AF
        CALL B2HEXDP
        LD A,(CHARBUF)
        CP 1A;^Z
        RET Z
        CALL B2HEXDP
        POP AF
        OR A
        JP NZ,KEYIN
NEXT:CALL SPDP
        JP LOOP
KEYIN:LD C,01
        CALL FCALL
        CALL ADP
        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
        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
        LD C,02
        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;$
;

下はアセンブルリストです。

2012/3/22  20:45  fnc0bt1.txt
END=818B
              ; BDOS function0B test
              ;2012/3/22
              ;
                ORG $8100
                FCALL=$8005
                CHARBUF=$C70E
              ;
8100 0E0B     LOOP:LD C,0B
8102 CD0580     CALL FCALL
8105 F5         PUSH AF
8106 CD5081     CALL B2HEXDP
8109 3A0EC7     LD A,(CHARBUF)
810C FE1A       CP 1A;^Z
810E C8         RET Z
810F CD5081     CALL B2HEXDP
8112 F1         POP AF
8113 B7         OR A
8114 C21D81     JP NZ,KEYIN
8117 CD3281   NEXT:CALL SPDP
811A C30081     JP LOOP
811D 0E01     KEYIN:LD C,01
811F CD0580     CALL FCALL
8122 CD3481     CALL ADP
8125 C31781     JP NEXT
              ;
              ;CL & LF
8128 3E0D     CRLF:LD A,0D
812A CD3481     CALL ADP
812D 3E0A       LD A,0A
812F C33481     JP ADP
              ;space disp
8132 3E20     SPDP:LD A,20
              ;A disp
8134 C5       ADP:PUSH BC
8135 E5         PUSH HL
8136 5F         LD E,A
8137 0E02       LD C,02
8139 CD0580     CALL FCALL
813C E1         POP HL
813D C1         POP BC
813E C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
813F C5       HEX4DP:PUSH BC
8140 E5         PUSH HL
8141 CD6981     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
8144 D5         PUSH DE
8145 EB         EX DE,HL
8146 CD5B81     CALL DEDP
8149 D1         POP DE
814A CD5B81     CALL DEDP
814D E1         POP HL
814E C1         POP BC
814F C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
8150 C5       B2HEXDP:PUSH BC
8151 E5         PUSH HL
8152 CD6F81     CALL B2HEX2
8155 CD5B81     CALL DEDP
8158 E1         POP HL
8159 C1         POP BC
815A C9         RET
              ;
              ;DE(asckii 2bytes) disp
815B D5       DEDP:PUSH DE
815C 5A         LD E,D
815D 0E02       LD C,02
815F CD0580     CALL FCALL
8162 D1         POP DE
8163 0E02       LD C,02
8165 CD0580     CALL FCALL
8168 C9         RET
              ;
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
8169 7C       B2HEX4:LD A,H
816A CD6F81     CALL B2HEX2
816D EB         EX DE,HL
816E 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
816F F5       B2HEX2:PUSH AF
8170 0F         RRCA
8171 0F         RRCA
8172 0F         RRCA
8173 0F         RRCA
8174 CD7E81     CALL B2HEX1
8177 57         LD D,A
8178 F1         POP AF
8179 CD7E81     CALL B2HEX1
817C 5F         LD E,A
817D C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
817E E60F     B2HEX1:AND 0F
8180 C630       ADD A,30
8182 FE3A       CP 3A
8184 D8         RET C;0-9
8185 C607       ADD A,07;A-F
8187 C9         RET
              ;
8188 696E     STRIN:"in"
818A 3A         DB 3A;:
818B 24               DB 24;$
              ;
ADP          =8134  B2HEX1       =817E  B2HEX2       =816F  
B2HEX4       =8169  B2HEXDP      =8150  CHARBUF      =C70E  
CRLF         =8128  DEDP         =815B  FCALL        =8005  
HEX4DP       =813F  KEYIN        =811D  LOOP         =8100  
NEXT         =8117  SPDP         =8132  STRIN        =8188  

[2012.3.25追記]
このテストプログラムにはバグがありました。
[第71回]で説明をしていますので、そちらをお読みください。
[追記ここまで]

アドレス8128Hから後は表示のためのサブルーチンで、今までのプログラムで使っていたものをそのままコピーしただけです。
Cレジスタに0BHを入れてシステムをコールします。
リターンしてきたらAレジスタの値をサブルーチンB2HEXDPで16進表示し、そのときのキャラクタバッファ(CHARBUF)の値も16進で表示します。
もしAレジスタの値が00でなければ、ファンクションコール01(コンソール入力)を実行して、入力された文字を表示します。

このプログラムを実行してみますと、残念なことに期待した通りには動作してくれません。
下はそのときのログファイルです。

>/ld fnc0bt1.bin,8100
loading FNC0BT1.BIN ...008c(140)bytes loaded,from 8100 to 818B
>jp d233

a>save 1 fnc0bt1.com
a>dir
A: FNC0BTST COM : FNC0BT2  COM : FNC0BT3  COM : FNC0BT4  COM
A: FNC0BT1  COM
a>fnc0bt1
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0061 0161aa 0000 000
0 0161aa 0000 0161aa 0000 0000 0000 0161aa 0000 0000 0061 0161aa 0000 0000 0000 
0061 0161aa 0161aa 0000 0061 0161aa 0000 0000 0161aa 0000 0161aa 0000 0161aa 000
0 0000 0000 0161aa 0000 0000 0000 0161aa 0000 0161aa 0000 0161aa 0000 0161aa 000
0 0161aa 0000 0161aa 0000 0000 0000 0000 0161aa 0000 0000 0000 0161aa 0000 0000 
0161aa 0000 0062 0162bb 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0
000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0
000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0
000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0
000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 

プログラムの実行中にキーボードからキー入力したのですが、入力されるときとされないときがあります。
どういうわけかキーによって入力されにくいものもあります。
これはWindows側のプログラム(ZB3.exe)がこのような動作を想定していないためで、そちらを直さないと期待通りの動きはさせられないようです。
ですから、ファンクションコール0Bについては、今はここまでにしておくことにいたします。

ワンボードマイコンでCP/Mを![第68回]
2012.3.22upload
2012.3.25追記

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