今月号と来月号でハードウェアを制作して外部機器 ( ? ) を制御します。ハードウェ アといっても℃ 3 つ , コンテンサ 4 つの P 円基板 , そして外部機器といっても抵抗 , ダイオード , スイッチだけの機器です。回路図も併記しますので , 工作に自信のあ る方もない方もせひ挑戦してみてください。ダイオードが自分の思うとおりにチカ チカ光っておもしろいですよ。ダイオードの代わりにメイク接点リレーなどを用い れば , 本格的な機器制御も夢ではありません。 第 106 ー CMAGAZINEZ 珥 3 = ホート人出力 ワン赭ント 上田哲ニ 概要 & ハードウェアの準備① プログラミング 講座 : 第 5 回 を制御て、きます。 CPU から周辺 LSI に命令を 下すときは , この I/O'* ートアドレスをもと は / 0 ポト制御 に制御すればよいことになります。すなわ ち各 LSI の I/O'* ートアドレスを知っていれ PC ー 98 て、は , さまざまな機能をもつ LSI の ば , 各 LSI を直接制御することが可能となる 制御を系統化するために , 各 LSI ごとに入出 わけて、す。 カ制御データ用の出入口として , I / O ポート C 言語から I / O ポートを介して各 LSI に命 が用意されています。 令を下すには inp ( ) 関数 , 情報を得るには I / O ポートには , I / O ポートアドレス ( 00H outp( ) 関数を用います。これらの関数は , ~ FFH) が割り当てられています。このアド MS ー C て、はヘッダファイル、、 conio. h 〃 , レスより制御データを入出力することて LSI LatticeC て、は、、 dos. h 〃て、定義されていま [ 表 1 ] I/O ボートアドレスの例 ポートアドレス 項番号 各種テノヾイス名 bo O O O 0 O 割り込みコントローラ 4PD8259A ( マスタ ) O X O O O O X O 割り込みコントローラ 4PD8259A ( スレープ ) O O O AI A3 A2 1 DMA コントローラ 4PD8237A -5 O O 1 O X X X O カレンダ時計 PD1990 O O 1 1 X X O 日 S ー 232C インタフェイス 4PD8251A O O AO 1 1 X 1 システムボート 4PD8255A ー 5 O プリンタインタフェイス ( セントロ ) ″ PD8255A ー 5 O 1 O O X O 1 O O X X 1 キーボードインタフェイス 4PD8251A A2 AI AO O DGC ( テキストレ PD7220 1 O 1 A1 O C 日 T コントローラ 4PD52601 1 1 X 馬 1 タイマコントローラ PD8253 ー 5 O O GDC ( グラフィックレ PD7220 1 O 1 1 O 1 O AO 1 文字パターン ROM(CG) 1 ・つム (Y) 4 ・ LO ( 0 「 / 8 C) 4 ーっ乙 CO
( 第 4 回 ) 画面制御関数の作成 五ロ 高橋良明 前回までは , ファイルアクセスを行って を指定できません。今回は , 任意の X , Y 座標を指定して , テキスト画面を制御す きました。ファイルアクセスについては る関数を作成します。今回作成した関数 一段落しましたので , 今回は画面表示の を利用すると , より実用的なアプリケー 基本的な関数を作成します。コンバイラ ションを作成することかできます。 付属ライプラリでは , テータの表示位置 ② OS のファンクションコールを呼び出す きく 3 とおりに分かれます。これは , テキス テキスト画面制御の方法 ③ BIOS を呼び出す トのみならず , グラフィックやディスクア クセス , キーボード , そのほかの機能て、も そして , さらにテキスト画面て、は , ④ ASCII 制御コード , ESC シーケンスを利 ードウェアを制御する方法は , 使用す あてはまります。 ①ライプラリを呼び出す ーーる機能レベルによって , 次に示すように大 用する を加えた 4 とおりの方法て、制御て、きます。テ キスト画面制御て、は , ライプラリにない機 Fig. 1 機能の階層図 能を使用することが多いのて、 , 新たに関数 を作成する必要があります。 その際 , どのレベルの機能を使って , テ キスト画面を制御するかが課題になります (Fig. 1)0 プログラム OS のファンクション BIOS レ 0 ポート ソフトウェア ハードウェア OS のファンクション OS は , ハードウェアとプログラムとのイ ンタフェイスをとるものて、す。もしプログ ラムからライプラリを使用することがて、き ない場合 ( 使用したい機能がライプラリにな い場合 ) , 一般に OS のファンクションコール (BDOS : Basic DOS) を利用しなくてはなりません。 ファンクションコールは , どのプログラ ムて、もよく利用する機能をまとめたものて、 , 一種のランタイムライプラリというべきも のて、す。 ードウェアを直 OS のファンクションはハ 接制御しているのて、 , ユーザはめんどうな ードウェア制御を行わなくてもよいとい Fig. 2 MS ー DOS メモリマップ 番地 High COMMAND. COM MSDOS. SYS 9. S Y S Low 応用 C 言語 95
ES C シーケンス をサポートしています。 これはファンクションコールの上位に当 たる部分て、すが , MS-DOS のファンクショ ンコールは , 画面制御についての機能が不 足しているため ESC シーケンスなどをサポ ートしています。 今回は , この ASCII 制御コードと ESC シー ケンスを利用して , 画面制御を行います。 ASCII 制御コードは , ASC Ⅱコード体系の 0X00 ~ 0x1f まて、のコード ( 制御コード / コン トールコード ) をさすものて、す。そのうちて、 CRT 画面を制御するコードを利用すると , テキスト画面を制御て、きます ( 表 1) 。 ESC シーケンスとは , ESC コード (0x1b) て、始まる文字列 ( シーケンス ) のことて、す。 ESC シーケンスを利用して , テキスト画面 を制御することがて、きます。なお , ESC シ ーケンスはハードウェアによってサポート している機能が違うのて , 注意してくださ い ( 表 2 ) 。以後 , とくにことわりのないかぎ り , ASCII 制御コードと ESC シーケンスをま とめて ESC シーケンスということにします。 使用方法 ESC シーケンスは , 使用したい機能のシ ーケンス ( またはコード ) を CRT へ送る ( 画面 出力する ) ことによって利用て、きます。たと えば , ASCII 制御コードの 0x07(BEL) を CRT へ出力すると , ブザーが鳴ります。 同様に , ESC シーケンスの「 ESC = lc 」を CRT へ送ると , 1 ( 行位置 ) と c ( 桁位置 ) て、指 定した箇所へカーソルが位置づけられます。 出力方法 ESC シーケンスは , 文字列として出力し ます。後に示すサンプルプログラムにある ように char 配列に ESC シーケンスを設定し て , それを画面出力関数 ( printf など ) て、出 1 : 32 : } List 6 25 : 24 : 23 : 22 : 17 : 15 : return; printf("X. 4s",param) : csr-pos it (), y 十 i) : for(i=0;i く cnt;i + + ) : int i : 20 : stat ic char param[]={ESC,' [ ' 18 : VO i d clr-left(int x, int y, int cnt) 16 : / * clr_left LlSt 7 buzzer 1 : 2 : 3 : 4 : 6 : 7 : / * buzzer buzzer(void) VO i d putchar(BELL) : return; csr-fwd/csr-back/csr-up/csr-down LlSt 8 return; printf("X. 2s",param) : static char param ロ ={ESC, ・ (') : VOid csr-down ()O id) / * csr_down return; printf("X. 2s ". param) : static char paran0={ESC, 'M ・ } : VOid csr-up (void) 24 : / * csr_up return; printf("X. 4s ". paran) : param[2]=l; 17 : static char paran ロ ={ESC, ・ [,,0, ・ D ・ }: VO i d csr-back(void) 13 : / * csr_back return; printf("X. 4s",param) : param[2]=1; static char VO i d csr-fwd(void) 2 : / * csr_fwd 40 : 39 : 38 : 36 : 35 : 34 : 33 : 30 : 28 : 26 : 25 : 23 : 15 : 14 : 12 : 9 : 8 : 7 : 6 : 4 : 3 : 力します。 パラメータの指定方法 ESC シーケンスては , パラメータを渡す 100 CMAGAZINE 19 3
6 コンヾイラ に int ) のて、 , 本来の戻り値の型に変換するノ ードを生成します ( 25 ~ 30 行 ) 。関数呼び出 しを表す本構造は Fig. 5 のようになります。 制造 C のような近代的なプログラミング言語て、 は , 制御構造を表す文 ( if , while, do, for , case など ) をもっています。しかし , 機械語には , このような制御構造に直接対 応する命令はありません ( 実際には , 1 。叩命 令を備えている CPU もありますが , このよ うな命令は , 一般的なループ処理を行うと いうよりも , あるパターンのループを最適 化する命令と位置づけするのが適当て、しょ コンパイラがオプジェクトコードを生成 するときには , これらの制御構造を条件ジ ャンプ命令 ( C 言語て、は , if goto ・・・ ) に変換します。機械語の条件ジャンプ文は , C 言語て、の if ( 条件 ) goto ラベル ; に相当するものて、す。 たとえば , while ( 条件 ) を , if ・・ goto 文を使って書き直すと , again : if ( ! 条件 ) gotO exit 100P ; 文 造文は , 条件ジャンプに帰結させることが となります。このように , すべての制御構 exit 100P . goto again ; 文 Fig. 5 関数の木構造 ①バラメータがないとき ③バラメータが n 個のとき op_ FUNC 工 関数 ↓ ②バラメータがひとつのとき 1 番目のバラメータ 2 番目のバラメータ n 番目のバラメータ n ー 1 番目のバラメータ 1 番目の バラメータ の内部を詳解 て、き , また実際に生成されるコード中て、は 条件ジャンプによって表現されているわけ て、す。 ところて、 , 式の説明をしているときに 急に制御構造の話をしたのて、 , 不思議に思 われる方もいらっしやると思います。この 理由は , 式と制御構造とは密接な関係があ るためて、す。 bo 式の扱い 制御構造の「条件」は , 論理値てなければ なりません。つまり , 条件が成立すれば真 , 成立しなければ偽 , という 2 とおりのどちら かに決められなければならないわけて、す。 Pascal などの型にうるさい (strongly typed) 言語て、は , 真か偽かの論理値を表す論理型 ( またはプール型 ) という独立した型が規定 されているのがふつうて、す。比較演算の結 果は論理型になり , 論理演算 ( and , or など ) は論理型のオペランドを取り , その結果も また論理型になります。 それに対して , C 言語て、は , 論理型を導入 せずに , int 型て、代用しています。論理値と してみた場合 , 0 以外が真 , 0 が偽と判断さ れます。比較演算子の結果は int 型て、 , 真な ら 1 , 偽なら 0 と定められています。このよ うに , C て、は , 論理値と数値とを区別せず に , 混同して使用するようになっており , PascaI とは対照的て、す。 また , C 言語て、は , 条件演算子 ( ? : ) , 論理 AND 演算子 (&&), 論理 OR 演算子 ( 凵 ) は , 外見上はふつうの演算子てすが , 実は 内部に制御構造を隠しもっている点にも注 意しなければなりません。 コード生成という面からみると , C 言語の 場合 , 定義に従った素朴なインプリメント を行った場合 , 比較演算のコードはたいへ yacc による C コンバイラブログラミング 69 ない ( つまり , 真てある ) ならば , 関数 f00 を そして , 後半ては , ax レジス・タの内容が 0 て 1 , 偽なら 0 を ax レジズタにセットします。 (Fig. 6(a))0 前半て、は , a = = b が真ならば ん非効率なものになってしまいます
力へ流れる矩形波の ON / OFF のタイムイン アドレスおよびにコントロールコマンドは P 日による外音 ~ ターバルさえも制御て、きるのて、す。 表 2 ~ 4 に示すとおりて、す。 の帋 スピーカ周波数設定はタイマ LSI のカウン さて , 問題の PPI 基板て、す。お金があるな タ # 1 て、行い , I / O ポートアドレスは 0x3FDB ら何万円も出して PPI 基板を買えばよいのて、 て、す ( たしか U / VF 以降はこのアドレスが有 すが , 工作好きの ( お金持ちて、ない ) 私とし P 円反と作成 効て、す ) 。このアドレスに 2 バイト ( 16 ビット ) ては自作することをお勧めします。 1 万円ほ の値を設定することによって , スヒ。ーカ周 どて、つくることがて、きます。部品点数は少 波数を決定て、きます。設定する値 n と周波数 表 1 の中にもいくつか使われていました ないのて、すが , 配線数が多いのて、まちがえ F ( kHz ) の関係は本体の CPU クロック周波数 が , 今回の主役は 8255A という LSI て、す。 ないようにハンダづけしてください CLOCK(MHz) に比例し , れは PPI(Programable PeripherraI ツリスト , 回路図 , IC のヒ。ン配置などの資 F = 245760 * CLOCK/n lntreface) と呼ばれ , 周辺用 IC として広く使 料を付記します。また , 制御外部機器とし のようになっています ( たぶん ! ? ) 。 用されています。 PPI には , 3 つのパラレル て , 実験用 LED スイッチ基板の回路図も載 値 n を入力すると , その値て、よいかどうか I / O ポート A , B , C とひとつの制御用ポート せておきます。次回はこれらを使ってポー 答えるまて、のあいだ , 値 n による周波数 F の があり , 合計 24 ビットの入出力の制御がて、 ト入出力による機器制御を行います。 音を鳴らし続けます。 きます。ポート A, B は 8 ビットごとの入出 P 日基板 , こて、ストップキーなどて、プログラムを 力の制御て、すが , ポート C は上下 4 ビットご 中断してしまった方は , サンプル 1 のプログ とに入出力制御がてき , また出力だけなら 参考文献 : 『 PC 工作入門』 , 斎藤浩之 , 日本 ラムて、止めてください ば 1 ビットごとに制御て、きます。各ポートの ソフトバンク刊 Fig. 2 回路図 本体側カードエッジコネクタ ⅲ海第 3 石篠ー フラットケープルヘッダ PAO PAI PA3 PA4 PA5 PA6 PA7 PAO PA2 PA3 PA4 PA5 PA6 PA7 P80 PB2 PB3 PB4 PB5 PB6 PCO PCI PC2 RESET PC3 PC5 PC6 PC7 8 8 っ 4 っ ℃ k8255A ー 5 ℃ 2 : 74LS138 ℃ 3 : 74LS00 PB2 PB3 PB4 PB5 P86 PB7 PCO PC2 PC3 PC4 PC5 PC6 PC7 GI 62A A5 A6 A7 CPUENB 第ロ 1 5 35 ℃ 3 RESET 834 A33 A34 10 日 10W 36 A49 A50 849 850 A 1 1 B41 B22 823 十 5V 33 34 16 26 14 GND GND に 1 ℃ 3 に 2 1 6 18 0.1 材 0.1 ′ 十 12V 十 12V 日 32 833 ー 12V ー 12V 32 ワンポイントプログラミング講座 109
間の間隔がアバウトて、よいような制御なら ば , このように非常に簡単て、す。ブザーの ON/OFF プログラム beep を List1 に示します。 引数を判定して , ブザーの ON/OFF を振 り分けているだけのプログラムて、す。引数 の文字列の大小文字は区別せず , 指定の引 数以外ならば使用法を表示して終了します。 このプログラムて、は , ブザーを ON にしたら 音が鳴りつばなしになります。好きなとき にこのプログラムを使って止めてください サンプルプログラム 2 PC ー 98 本体のビープ音は , 実は , プログラ マプルインターバルタイマというタイマ LSI を用いて矩形波をスヒ。ーカに送っているだ けなのて、す。このおおもとのスイッチの制 御がサンプル 1 て、あったわけて、すが , スヒ。ー Fig. 1 PPI ( 8255A ) のプロック図 List 3 ・ー十レ 0 し 0 X 0 十しワ 3 ・ー 0 十》 0 0 0 0 14 り 0 っ 4 ′ 0 CD ー 8 0 14 っ 0 っ 0 -4 - -0 ^ 0 ? ー 8 0 1 ーり 0 れ 0 -4- - -0 ー 8 ・ 1 、 1 ー 1 1 よ 1 よ、 1 1 ー、 1 、 1 っ 0 っ 0 ワ 0 ワ 0 っ 0 り 0 っ朝ワ 0 ワ 0 り 0 っ 0 っ 0 っ 0 っ 0 っ 0 っ 0 っ 0 っ 0 っ 10000 ( く - tine interval)" 入出力 PAo—RAI グループ ・ボート A ( 日 ) グループ 制御 入出力 PCrPC7 グループ ポート C 上位 ( 4 ) グループ ボート C 下位 ( 4 ) ア タスフ ッ テパパ ス タ テ a 入出力 PCo—PC3 R D 0 ーーーーー 40 WR ライト 制御 RE ET グループ 制御 入出力 PBo—PB7 グループ ポート B 旧 ) CS 108 CMAGAZINE 19 3
五ロ 用 応 ー DOS が各機種専用になっているのは , この 部分が原因て、す。 一方 , MSDOS . SYS は COMMAND . COM やアプリケーションプログラムとのイ ンタフェイスをとります。このため , MS- DOS はバージョンが同じて、あれば , 外見上 はどの機種て、も同じインタフェイスになっ ています。 さて , 現在発売されているアプリケーシ ョンソフトウェアはマシン依存のものがほ とんどて、す。なぜて、しようか ? OS のファンクションだけを利用していた のて、は , ハードウェアの性能を十分に引き 出せないからて、す。とくに画面制御に関し て , OS のファンクションと BIOS て、は , 機能 とスビードに格段の違いがあります。 そのため , ほとんどのアプリケーション ソフトウェアて、は , BIOS も使用しているわ けて、す。 put_str 1 : 2 : / * put-str 3 : put-str(int x, int y, char *buf, int cnt) 4 : VO i d csr-posit (), y) : 6 : printf("X*s", cnt, buf) : 7 : 8 : return; List 2 put_chr 1 : 2 : / * put-chr 3 : put-chr(int x, int y,char chr) 4 : VOid csr-posit(x,y) : 6 : printf("%c",chr) : 7 : 8 : return; List 3 cls 1 : 2 : / * cls 3 : cls(void) 4 : VO i d param ロ ={ESC, ' [ ' 6 : static char 7 : printf("%. 4s", param) : 8 : 9 : return; 10 : } List 4 / / 0 ポート さて , すて、に述べたように BIOS はよく利 用される機能をまとめたものて、すが , もし 利用したい機能が BIOS にもない場合は , 「 I/ ()'* ート」を呼び出さなくてはなりません。 しかし , 一般にはよほどおかしなことを行 わないかぎり , I/O ポートを呼び出すなどと いうことはありません。 BIOS にしても , I/O* ートにしても , ハ ードウェアを直接呼び出します。 ェアを直接制御する場合には , ハードウェ ア情報はもとより , ハードウェアの知識を 豊富にもっている必要があります。その意 味て、 , 今回はソフトウェアレベルて、の機能 を利用するだけにとどめておくことにしま す。 SC ー制御コードと ESC シーケンス テキスト画面制御に関して , MS-DOS は ファンクションコール以外に ASCII 制御コード clear List 5 1 : 2 : / * clear 3 : clear(int Y) 4 : VO i d param[]={ESC, ・ [ ' 6 : static char 7 : csr-posit(l,y) : 8 : printf("X. 4s",param) : 9 : return; clr_right/clr_left 1 : 2 : / * clr_right 3 : 4 : VOid clr-right(int x,int y,int cnt) 6 : static char param[]={ESC, ・ [ ' 7 : i nt i : for(i=0;i く cnt,•i + + ) 8 : 9 : csr-posit(x,y 十 i); printf("X. 4s ” , param) : return; List 6 応用 c 言語 97
1989 年 7 月発売以来、 MS - DOS 上のリアルタイムシステム構築ツールとして こ好評をいただいている Lattice C/RT0 まだ、導入を迷ってられる方のた めに、誌上を借りて、こ質問にお答えします。 FA 、 LA システムを始め、各種 ßLattice C/DOS Ve 「 . 4 」と完全に互換性があります。 ことをお勧めします。 プラにしなければならないこともあり、できるだけ、アセンプラて記述する とが望ましく、作成するシステムの割り込み間隔の関係などにより、アセン C で記述可能です。しかし、割り込み処理はできるだけ短時間に終了するこ 別のタズクー D を割り当てることによって実行て、きます。 管理は、ユーサーが行う必要があります。 ションコールか出来ます。但し、排他制御はしていませんから、リソースの ョンコールに対して、エミュレートしているので、タスク内からのファンク プしているものがあります Lattice C / 日 T ては、そのようなファンクシ 可能です。 MS-DOS のファンクシ白ンコールの中には、入力待のままルー 20 ミリ秒の整数倍て指定できます。 32 タスクてす。 可能となります。 り込みで起動するタスクをイベント・ドリプン・タスクに指定することて、 したがって、一定時間毎に起動するタスクをタイムスライス・タスクに、割 べント・ドリプン方式とタイムスライス方式の両方をサポートしています。 可能です。 Lattice C / 日 T はマルチタスク処理を実現する方法として、イ リアルタイムシステム構築に Lattice C / 日 T をこ使用ください。 住 Lattice C / DOS との互換性 ますか ? 回割り込み八ンドラは、 C で書け ますか ? 6 同じタスクを 2 個以上実行でき 可能ですか ? ル (int 21H ) をタスク内で実行 国 MS ーロ OS ファンクションコー 回タイムスライス間隔は ? 国最大タスク数は ? 移るということがてきますか ? きに直ちに別のタスクに処理が 動しつつ、割り込みがあったと 回一定時間おきにあるタスクを起 がありますか ? リ刀レタイム・マルチタスクシステム構築専用 C コン督ラ レ / 側 A [ 4.1 【対応機種】 >PC ー 98 ( L 丁を除く ) FM 日 50 / 60 / 70 価格 Panacorn M500 / 6 開 / 700 >J ー 31 シリース ( 日本語モート ) >AX 仕様機 ( 日本語モート ) ¥ 238 , 000 ELattice C / 日 T マルチタスク ①タスクの実行制御 関連ライプラリー ( 抜粋 ) wait—mefn req—tsk abort—tsk eds—exit wait— . sefn req—tl m task—exit walt—SIgn can—tlm dcl—sch 複数イベント待ち タスク実行要求 タスク実行停止 DOS に制御を移す 単一イベント待ち タイマー要求 タスク実行終了 シグニフィカントイベント待ち タイマー・キャンセル スケジュール要求 ②タスク間通信 send—data テータ送出 send—rdata リージョン領域を使った送出 send—sts ステータス送出 リージョン領域を使った受信 rcv—rdata rcvl—data データ受信 ( ポート 1 ) rcv2—data テータ受信 ( ポート 2 ) 3 イベントフラグ制御 イベントフラクのセット set—efn read—efn 全イベントフラグ情報の読み込み イベントフラグのリセット rst—efn イベントフラグの状態テスト tst ー efn 0 タスク属性制御 自己タスクのフライオリティ変更 ・タスクステータスの変更 タスクのステータスの読み込み read— StS タスク id の読み込み read—tid 0 時計制御 read—tim 時刻・日付テータの読み込み set—tim 時刻・日付データの設定 ・パッフア制御 バッフア領域の確保 get— buf パッフア領域の解放 rel—buf ①入出力ドライバー制御 alt—prt 国システムがかなり大きいのです が、 Lattice C / 日 T で構築で きますか ? んか ? 6 台分購入しなければなりませ いますが、 Lattice C/RT を 回現在 6 台のノヾソコンて開発して すか ? を買い直さなけれはならないで っているが、 Lattice C/RT @既に Lattice C/DOS を持 2 つの方法かあります。 1 番目は、タスクの起動までに時間がかかってもよ ュ、タスクを非常駐タスクに指定することによって、タスクをティスク上に置 いておくことかできます。非常駐タスクは実行時に、メモリにロードされ、 実行を終了すると、メモリは解放されます。 2 番目の方法は、タスクを EMS メモリに置くように指定する方法です。 Lattice C/ 日 T は EMS Ve 「 . 4.0 をサホートしています。 EMS に置ける 1 つのタスクの大きさは、 64KB まての大きさに限られます。ー ßLattice C/DOS 、 Lattice C/DIJAL 、 Lattice C / 16M 、日 OMa- ble C を既にお持ちのユーサーか凵 FEBOAT ー NDEX から購入される 場合には、特別ティスカウントシステムとして、 5 万円割引となります。 複数のパソコンで開発する場合、割安に購入するためのコーポレトライセ ンスがあります。通常のバッケージソフトは 1 台のパソコンに 1 本のライセ ンスて販売されています。 6 台の / ヾソコンを使うときは、 6 個のソフトを購 入しないと不正コピーという事になります。そこて凵 FEBOAT では、まと めて割安に購入できるコーポレートライセンスで、不正使用の不安なくこ使 用いただけるようにしております。コーボレートライセンスについては、 凵 FE 日 OAT 営業 1 課 ( TEL : 03 ー 293 ー 4714 ) まてお問い合わせください。 rcv— lOPk red—dev dcl —dev request—10 asn—dev iO—done レ 0 バケット受信 入出力リダイレクト設定 デバイス制御ルーチンの登録 入出力要求発行 テ・バイス制御ルーチンのアサイン 入出力完了処理 0 割り込み制御 cnt—vec sw—task ⑩コモンテ・ dCl —cmn get—cmn cnt—cmn write——cmn put—cmn read. —cmn intSV sw——exlt OS / 2 MS - DOS 両用 C コン督ラ MS OS / 2 、 MS - DOS 両 OS をサホートする Lattice C コンバイラ。 OS / 2 は、 LAN サーバやゲートウェイサーバとして、また M M L ( M i c 「 0 Mainf 「 ame Link ) を必要とするパソコンの OS として今後の普及か期待さ れています。しかし、 OS / 2 は新しい OS なので、 OS / 2 用のプログラムを新た に開発していかなければなりません。このとき、 MS - DOS にある多くの Lat - tice C の資産を移植して行くためには、 0S/2 上の Lattice C か不可欠で す。 Lattice C/DIJAL は Lattice C/DOS Ve 「 . 4.1 と完全に互換性か あり、資産の継承を安心して行えます。 【対応機種】 PC ー 9800 ・・ FM 日・ >Panacom PS / 55 ・・ >PC AT ・・・ >J -3100 ・・・ ペクターアドレス登鉧 フォーク処理実行 割り込み前処理情報保存 フォークモード終了 ータ制御 コモンエリア登録 コモンデータの取得 コモンエリア接続 コモンエリアへのテータ書き込み コモンエリアへの 1 ワード書き込み コモンエリアのデータ読み込み 価格 ・・・¥ 128 , 000 ・・・¥ 128 , 000 ・・・¥ 128 , 000 ・・・¥ 98 , 000 ・・・¥ 98 , 000 ・・・¥ 128 , 000 く日本語〉 MS OS / 2 または旧 M く日本語〉 OS / 2 搭載機
39 : 40 : 41 : 42 : 43 : 44 : 45 : 46 : 47 : 48 : 49 : 50 : 51 : 52 : 53 : 54 : 55 : 56 : 58 : 59 : 60 : 61 : 62 : 63 : 64 : 65 : 66 : 68 : 69 : 70 : 71 : 74 : 76 : 77 : 79 : 82 : 83 : 84 : 85 : 86 : 88 : 89 : 90 : 92 : 93 : 95 : 96 : 98 : 99 : 100 : 101 : 102 : 103 : 104 : 105 : 106 : 107 : 108 : 109 : 1 1 0 : Ⅱ 1 : Ⅱ 2 : List DX, CS:taskSS AX. CS:taskSP 1 void* from_scheduler(unsigned state[]) : こでスケジューラがほかのタスクに制御を渡し , ほかのタスクはスケジューラへとリターンします。 stack_save_SP dw ? stack_save_SS dw ? mov BP, SP push BP from_scheduler PROC FAR taskSP dw ? taskSS dw ? : 制御が戻るときにリストアされるのは CS コ P だけです。 : しかし ES はコンパイラによって違います。スケジューラの C + + 側が必要とするなら , : D フラグをリセットしています。引と田のセープはかなり標準的です。 : 私は , 割り込まれた関数が文字列操作の最中だった場合に備えて , 方向フラグは前向きへとセットされていなければならない。・・・とあります。 関数は AX, BX, C X, DX, ES を変えてもよい。 関数は SI,DI,BP. SP , SS. CS , DS を保全しなければならない。 : Zortech のマニュアルの 233 ページには : : コードセグメント内の変数から SS : SP や , そのほかのレジスタをリストアできます。 これは実行場所を示すので , 当然必要です。 :SI と DI のセープもする必要がありません。 こに ES のセープを書き加えるべきです。 C + + 側が必要としなければ , : いまや , 割り込まれたタスクのステートのリストアができる。 これでスケジューラのステートのセープが完了。 mov CS:stack_save_SP,SP mov CS:stack_save_SS,SS push DS push 田 push 引 : すべてのブッシュの後で , スタック・ポインタをどこか安全な場所にストアする。 lds BX, [BP + 6] AX, DS SS, AX SP, BX AX BX CX DX SI BP ES DS POP POP POP POP POP POP POP POP POP mov mov : SS : SP の元の値 ;SS and SP : 続けてロードしなければならない dec CS:preempt-inhibit : 円 ags コ P, CS をポップ from_schedul er ENDP これは後半部分の関数です。 94 : to_scheduler PROC FAR これはスタックをリストアしてスケジューラにリターンします。 : 割り込みはここにジャンプします。 mov mov POP POP POP POP cld mo V mov ret SS. CS:stack-save-SS SP. CS:stack_save-SP : SS と SP は続けてロードする BP DS to_scheduler ENDP void task_yield() スケジューラに制御を渡します。 task-yield PROC FAR inc CS:preempt_inhibit ;CS.I P はすでにスタック l. にあります。 : スタックが 0 RET による ) リターン川正しく設定されている心要があります。 : つまりリターン・アトしスのにフ 1. , グを挿 ) 、する心要があります。 い ( ) い AX : 0 ⅵ n 心 Ret Addr いいい BX 汎Ⅲしゞ・・スとフラグはセープしませんが , 以下略。付録ディスクを参照してください。 るようなものて、す。この記事て、は , 先制制 御システムの落とし穴と , それらの解決方 法を説明します。 C 十十はマルチタスキングのライプラリを 書くのに非常に適した言語て、す。多くの複 雑な構文を , いくっかのクラスの中にこじ んまりと閉じ込めることがて、きます。各種 の機能を確実に正しく使うことがて、きるよ うにするために , コンストラクタとディス トラクタという仕組みが便利に利用て、きま す。しかし C 十十は , いくつかの非常に重要 な領域て、能力不足て、す。 ■タスクスイッチの処理 第ハードウェア割り込みでコールされる関 数の設定 ■先制制御の下での相互排除の実現 これら 3 つのことは , すべてアセンプリ言 語を使えば簡単にて、きます。これらのプリ ミテイプさえ作れば , ライプラリのそのほ かの部分は C 十十て、書けます。 PRIM. ASM (List1) に , 先制制御方式のマルチタスクカ ーネル用の , アセンプリ言語のプリ、 ミティ ア割り込みの結果として実行されるのて、 , タスクスイッチを行う関数はハードウェ つの別々の関数を使うことになります。 両者はスタックの使い方が違うのて、 , ふた または自発的な制御放棄方式て、行うかて、す。 式のタスクスイッチの一環として行うか , まったく違う方法があります。先制制御方 する操作が伴います。これには , 2 とおりの プして , 別のタスクのステートをリストア これにはひとつのタスクのステートをセー は , 複数のタスクの切り換えをすることて、 , マルチタスクライプラリの中心的な機能 タスクスイッチの仕組み ウェアの知識がなくても使えます。 分を隔離すれば , このライプラリはハ きるて、しよう。ハードウェアに依存する部 て、すが , ほかのシステムにも容易に移植て、 プがあります。今回のコードは MS-DOS 用 C + + による先制制御方式のマルチタスキング コール時の環境は事前にはまったくわかり 11
のマルスキンク LANGUAGE 提載記事 C 十十による先制制御方式 D 旧 gosz / 岩谷宍 (COMPUTER LANGUAGE/Nov. 1 989 ) John ( RJTER LANGUAGE 響ー田物 MULTITASKING C 十十を使い , マルチタスクカーネルを作成するこの るものとは一線を画している。本記事では , 困難とさ マルチタスクカーネルは , 先制制御方式とれる強 れているタイマ割り込みの管理を , C 十十とアセンプラ 制的なタスクスイッチング方式を導入していることか をうまく組み合わせ ( やはり , アセンプラは使わざるを 大きな特長となっており , 単純なタスク切り替えによ えない ) , タスクのコントロールをしている。 1988 年に , 私は C による単純なマルチタス クカーネルのソースを提示しました (A Multitasking Kernel for C Program mers/COMPUTER LANGUAGE , Oct. 1988 , pp. 49-61) 。今回はその続編て、すが , 前編とは大きくふたつの点て、違っています。 ひとつは先制制御 (pre-emption) をサポート していることと , もうひとつは C 十十て、書い たことて、す〔訳注 : こて、、、先制制御クと訳 している pre-emptive" は , タイムスライ スによる画一的 , 強制的なタスクスイッチ 方式のことて、す〕。 この前の私の記事て、は , 単純なタスキン グシステムの作り方をお見せしました。タ スクスイッチを行う関数は単純に , スタッ クポインタのセープと新たなロードの , く普通の関数構造とリターン方式て、 , レジ スタを適切にセープすることがて、きるもの て、した。プロセスは自分が OK なときだけ制 御を放棄するのて、 , 競合状況は存在しませ んて、した〔訳注 : ' 88 年 10 月号て、紹介されたマ ルチタスクカーネルは , キューに並んて、い るタスクを順番に実行していく , というだ けのものて、した〕。 先制制御は , パンドラの箱を新たに開け List 1 PRIM. ASM C 叩 yright 1989 by Dlugosz Software これは C 十十によるマルチタスク・システムに必要な , アセンプリ言語のプリミテイプ集て、す。 これは Zortech C 十十の large model 用に書かれており , MASM 5.1 て、アセンプルするという前提て、す。 . MODEL し ARGE 2 : し S. 3 : PUBLIC _from_scheduler, ta.sker• install, 4 : PUBLIC _preempt_off, ta sk Y i 引 d prccmpt ( 川 . 5 : : for debugg ing ・ 6 : PUBLIC to scheduler, new timer-tick 7 : 8 : . DATA 9 : _DS dw SEG DGROUP . CODE 13 : old_timer し ABE し DWORD 14 : old_timer_ofs dw ? 15 : old_timer_seg dw ? 17 : preempt-inhibit dw 1 : 先制制御が禁止されている : void preempt-off ( ) : 20 : : VOid preempt_on() : 22 : このふたつの関数は preempt_ i n h i b i t f lag のステートを変えます。 23 : これらをここに入れたのはふたつの理由からです : 24 : 1 ) ステートの変更は不可分のサイクルで行わなければならないが , 25 : コンパイラがそういうコードを生成するという確証がないため。 2)Zortech C + + は FAR 変数にアクセスできず , このフラグは DGROUP の中にはないため。 26 : 27 : これはタイマー割り込みの CS EG 内でなければならない。 28 : 29 : -preempt_off PROC FAR 30 : inc CS:preempt-inhibit ret 32 : -preempt_off ENDP 33 : 34 : -preempt-on PROC FAR 35 : dec CS:preenpt-inhibit 36 : ret -preempt-on ENDP 38 : tasker_remove 10 CMAGAZINE 1990 3