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

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

[第91回]


●ファンクションコール1CH、1DH(ライトプロテクトセットとR/Oベクトルの取り出し)

ファンクションコール1CHはカレントドライブにライトプロテクトをかけてリードオンリーにします。
R/Oベクトルは前回のログインベクトルと同じ形式で、16ビットの値のうち、リードオンリーになっているドライブに相当するビットを1にしたものです。
ファンクションコール1DHはR/OベクトルをHLレジスタに入れて戻ります。

ファンクションコール1CHをテストするFTST11と、ファンクションコール1DHをテストするFTST12を作成します。

まずはFTST11.TXTのソースリストです。

; BDOS TEST11 set 'read only ' function1C
;2012/4/10
;
     	ORG $8100
     	FCALL=$8005
;
	LD C,1C
	CALL FCALL
	RET
;

とても簡単なプログラムです。
Cレジスタに1CHを入れて、システムをコールします。
ファンクションコール1CHは、カレントドライブをリードオンリーにします(他のドライブを指定することはできません)。

FTST11.TXTをZASM.COMでアセンブルします。
下はアセンブルの結果作成されたアセンブルリストです。

2012/4/10  11:19  ftst11.txt
END=8105
              ; BDOS TEST11 set 'read only ' function1C
              ;2012/4/10
              ;
                   	ORG $8100
                   	FCALL=$8005
              ;
8100 0E1C     	LD C,1C
8102 CD0580   	CALL FCALL
8105 C9       	RET
              ;
FCALL        =8005  

次はFTST12.TXTのソースリストです。
Cレジスタに1DHを入れてシステムをコールします。
そのあとHEX4DPをコールしてHLレジスタの値を16進4桁で表示します。

今気がつきました。
このプログラムにはおかしなところがあります。
わざとこのようにしたわけではありません。
うっかりです。
でもたまたま間違いにはなりませんでした。
メイン部分の最後はRETにするべきところなのですが、それがなくてサブルーチンCRLFにつながってしまいました。
テクニックとしてはこういうプログラムもあり、なのですけれど。
サブルーチンCRLFの終わりもRETではなくて、JP ADPになっています。
ここは意識的にしています。

; BDOS TEST12 get r/o vector    function1D
;2012/4/10
;
        ORG $8100
        FCALL=$8005
        FCB=$805C
;
        LD C,1D
        CALL FCALL
        CALL HEX4DP
        ;
;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
;
;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
;hex to binary, ascii 1charactor to low 4bit 
HTOB1:CP 30;>="0"?
        RET C;no
        CP 3A;<="9"?
        JP C,HTOB1_2;yes,"0" to "9"
        CP 41;>="A" ?
        RET C;no
        CP 47;<="F"?
        JP C,HTOB1_1
        CP 61;>="a"?
        RET C;no
        CP 67;<="f"?
        CCF
        RET C;no
HTOB1_1:ADD A,09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
HTOB1_2:AND 0F
        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
;

FTST11と同じでメインプログラム部分は短いのですけれど、HLレジスタの値を16進数で表示するために、そのためのサブルーチンを以前のテストプログラムからコピーしたために全体は長いプログラムになってしまいました。
表示のためのサブルーチンは[第42回]で作ったDMプログラムからコピーしました。

FTST12.TXTをZASM.COMでアセンブルします。
下はアセンブルの結果作成されたアセンブルリストです。

2012/4/10  11:19  ftst12.txt
END=8183
              ; BDOS TEST12 get r/o vector    function1D
              ;2012/4/10
              ;
                        ORG $8100
                        FCALL=$8005
                FCB=$805C
              ;
8100 0E1D       LD C,1D
8102 CD0580     CALL FCALL
8105 CD5A81     CALL HEX4DP
                ;
              ;CL & LF
8108 3E0D     CRLF:LD A,0D
810A CD1481     CALL ADP
810D 3E0A       LD A,0A
810F C31481     JP ADP
              ;space disp
8112 3E20     SPDP:LD A,20
              ;A disp
8114 C5       ADP:PUSH BC
8115 E5         PUSH HL
8116 5F         LD E,A
8117 0E02       LD C,02
8119 CD0580     CALL FCALL
811C E1         POP HL
811D C1         POP BC
811E C9         RET
              ;
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
811F 7C       B2HEX4:LD A,H
8120 CD2581     CALL B2HEX2
8123 EB         EX DE,HL
8124 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
8125 F5       B2HEX2:PUSH AF
8126 0F         RRCA
8127 0F         RRCA
8128 0F         RRCA
8129 0F         RRCA
812A CD3481     CALL B2HEX1
812D 57         LD D,A
812E F1         POP AF
812F CD3481     CALL B2HEX1
8132 5F         LD E,A
8133 C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
8134 E60F     B2HEX1:AND 0F
8136 C630       ADD A,30
8138 FE3A       CP 3A
813A D8         RET C;0-9
813B C607       ADD A,07;A-F
813D C9         RET
              ;hex to binary, ascii 1charactor to low 4bit 
813E FE30     HTOB1:CP 30;>="0"?
8140 D8         RET C;no
8141 FE3A       CP 3A;<="9"?
8143 DA5781     JP C,HTOB1_2;yes,"0" to "9"
8146 FE41       CP 41;>="A" ?
8148 D8         RET C;no
8149 FE47       CP 47;<="F"?
814B DA5581     JP C,HTOB1_1
814E FE61       CP 61;>="a"?
8150 D8         RET C;no
8151 FE67       CP 67;<="f"?
8153 3F         CCF
8154 D8         RET C;no
8155 C609     HTOB1_1:ADD A,09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
8157 E60F     HTOB1_2:AND 0F
8159 C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
815A C5       HEX4DP:PUSH BC
815B E5         PUSH HL
815C CD1F81     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
815F D5         PUSH DE
8160 EB         EX DE,HL
8161 CD7681     CALL DEDP
8164 D1         POP DE
8165 CD7681     CALL DEDP
8168 E1         POP HL
8169 C1         POP BC
816A C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
816B C5       B2HEXDP:PUSH BC
816C E5         PUSH HL
816D CD2581     CALL B2HEX2
8170 CD7681     CALL DEDP
8173 E1         POP HL
8174 C1         POP BC
8175 C9         RET
              ;
              ;DE(asckii 2bytes) disp
8176 D5       DEDP:PUSH DE
8177 5A         LD E,D
8178 0E02       LD C,02
817A CD0580     CALL FCALL
817D D1         POP DE
817E 0E02       LD C,02
8180 CD0580     CALL FCALL
8183 C9         RET
              ;
ADP          =8114  B2HEX1       =8134  B2HEX2       =8125  
B2HEX4       =811F  B2HEXDP      =816B  CRLF         =8108  
DEDP         =8176  FCALL        =8005  FCB          =805C  
HEX4DP       =815A  HTOB1        =813E  HTOB1_1      =8155  
HTOB1_2      =8157  SPDP         =8112  

●FTST11.COMとFTST12.COMのセーブ

いつものようにログファイルで説明をいたします。
ZB3BASICにエントリして、
/LD FTST11.BIN,8100[Enter]
を実行します。
そのあと
JP D233[Enter]
でCP/Mを起動し、
save 1 ftst11.com[Enter]
と入力し、FTST11.COMというファイル名でAドライブにセーブしました。
そのあと、[Ctrl][D]を入力して、一旦CP/Mを終了してZB3BASICに戻っています。

logfile nd80zlog\04101124.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
>/ld ftst11.bin,8100
loading FTST11.BIN ...0006(6)bytes loaded,from 8100 to 8105
>jp d233

a>save 1 ftst11.com
a>^D
end of CP/M
>/ld ftst12.bin,8100
loading FTST12.BIN ...0084(132)bytes loaded,from 8100 to 8183
>jp d233

a>save 1 ftst12.com
a>dir
A: FNC0E-1  COM : FTST10   COM : FTST10-2 COM : FTST10-4 COM
A: FTST10-5 COM : FTST11   COM : FTST12   COM
a>

今のところツールができていませんから、ハードディスクにあるファイルをCP/MのRAMディスクに保存するためには、まずZB3BASICの/LDコマンドでアドレス8100にロードしてから、CP/Mにエントリして、SAVEコマンドでセーブするしかないのです。

というわけで、ZB3BASICに戻って、
/LD FTST12.BIN,8100[Enter]
を実行します。
そのあと
JP D233[Enter]
でCP/Mを起動し、
save 1 ftst12.com[Enter]
と入力し、FTST12.COMというファイル名でAドライブにセーブしました。

●FTST11.COMとFTST12.COMの実行

最初にまずFTST12を実行しました。
リードオンリーになっているドライブはありませんから、R/Oベクトルは0000と表示されました。
次にFTST11を実行してから、もう一度FTST12を実行しました。
今度はカレントドライブ(Aドライブ)がリードオンリーになりましたから、R/Oベクトルは0001と表示されました。

本当にリードオンリーなのかどうか確認するために、SAVEコマンドで適当なファイル名でセーブを実行してみました。
すると
Bdos Err On A: R/O
と表示され、入力待ちになりました。

ここで[Enter]を押したところ
a>
と表示されました。

a>ftst12
0000

a>ftst11

a>ftst12
0001

a>save 1 test.txt
Bdos Err On A: R/O
a>b:
b>a:ftst11

b>a:ftst12
0002

b>

次にb:[Enter]
と入力して、カレントドライブをBドライブにしてから、
先にFTST11を実行して、Bドライブをリードオンリーにしてから、FTST12を実行しました。

あれ?
R/Oベクトルは0002と表示されました。
先にAドライブをリードオンリーにして、次にBドライブをリードオンリーにしましたから、0003になるはずなのですが…。

R/Oベクトルが0002になるわけがわかりました。
さきほどAドライブにセーブしようとしたときに、Bdos Errが表示されて、そこで入力待ちになりました。
何かキー入力したことで、そこでリブートが行なわれたのでした。
リブートが行なわれると、ディスクドライブの状態が初期状態に戻りますから、そのときにAドライブのライトプロテクトも解除されたのです。

今度はリブートしないように考えて、もう一度テストをしてみました。
最初にAドライブでFTST11を実行したあと、FTST12を実行して、R/Oベクトルが0001と表示されました。
次にBドライブをカレントドライブにしてから、そこでもFTST11を実行して、その後FTST12を実行しました。
今度はR/Oベクトルが0003と表示されました。

a>ftst12
0000

a>ftst11

a>ftst12
0001

a>b:
b>a:ftst11

b>a:ftst12
0003

b>^D
end of CP/M
>0000 00C3 - 
リモート接続を終了しました
logfile closed at Tue Apr 10 12:32:55 2012

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

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