<HTML>

<HEAD>

<TITLE>第２部</TITLE>

<META NAME="GENERATOR" CONTENT="Internet Assistant for Microsoft Word 2.0j Beta">
</HEAD>

<BODY>

<PRE>
<A NAME="BM2b"></A>　　第２部　　プログラム開発上の注意


<A NAME="BM1s"></A>　　　第１章　開発上の主な注意

　ＭＳＸでは、ほかの機種よりもプログラムを開発するときに注意すべきことが多く、
下手にプログラムを組むと、別の会社の機械では動かなかったというような現象がよく
起こります。ここでは、基本的なシステムでの注意事項を述べます。特定のオプション
機能については、別なところで述べます。


<A NAME="BM2_1_1"></A>　　　　２．１．１　ＲＯＭカートリッジの暴走

　ディスク内蔵機などで、ＲＯＭカートリッジが暴走する現象が知られています。これ
は主に、内蔵のディスクインターフェイスがスロット０の拡張スロットに置かれている
ＹＩＳ−８０５や、ＨＢ−Ｆ５００で起こります。シフトキーを押しながら立ち上げれ
ば、ちゃんと立ち上がるのですが、はっきりいって不便です。これは、ＲＯＭカートリ
ッジよりディスクインターフェイスが先に初期化を済ませてしまい、フリーエリアが減
っているにもかかわらず、そのままプログラムを実行してしまうために起こります。こ
れを回避するためには、ＲＯＭカートリッジが最初に
　　ＬＤ　ＳＰ，Ｆ３８０Ｈ
　としてスタックを初期化すればよいわけです。ただし、これはカートリッジヘッダの
ＩＮＩＴから直接実行を開始する場合です。また、ディスクドライブなどの機能を全く
使わないプログラムの場合だけ、この方法が使えます。このほかの場合にはスタックの
場所を変更するなどの方法が必要になります。


<A NAME="BM2_1_2"></A>　　　　２．１．２　裏ＲＡＭの検索

　裏ＲＡＭをワークエリアに使ったり、機械語サブルーチンを置いたりする場合には、
裏ＲＡＭのあるスロットを探さなくてはなりません。中には、ページ３のＲＡＭと同じ
スロットに裏ＲＡＭがあると思い込んでいて、裏ＲＡＭが別のスロットにある場合や、
拡張ＲＡＭカートリッジを使っている場合に動かないソフトがありました。コンピュー
ターの専門家がそんな間違いをするとはあまり思えないのですが、思い込みが強すぎる
とこういうことになってしまうようです。ＭＳＸでは、理論的に、すべてのページのＲ
ＡＭが、全く違うスロットにあることがありえますので、十分注意してください。
　ところで、ディスクをつないでいる場合と、そうでない場合は、裏ＲＡＭの検索の仕
方が変わります。順に説明しましょう。

　１．ディスクがつながっている場合。
　このときには、Ｆ３４１Ｈ番地からＦ３４４Ｈ番地までにＲＡＭのあるスロット番号
が書かれています。Ｆ３４１Ｈ番地がページ０の、Ｆ３４４Ｈ番地がページ３のＲＡＭ
のあるスロットということになります。ただし、ディスクのブートセクターを書き換え
て立ち上げた場合には、ゴミが入っている場合があります。また、ＭＳＸ１で、ＲＡＭ
３２Ｋ以下の機械では、裏ＲＡＭが存在しないために裏ＲＡＭのスロットを調べても意
味のある値は入っていません。

　２．ディスクがない場合
　ディスクがない場合や、本体のＲＡＭが６４Ｋであるかを調べるときは、次のような
方法を使います。
　調べたいスロットに値を書き込んで、読みだせるかどうかをチェックする。

　かなり原始的な方法ですが、これ以外に有効な方法がありません。
　具体的には、調べたいスロットから値を読んで、それを反転させて書き込み、再び読
んで書き込んだ値が読み込めるかどうかをチェックします。そして、元の値を再び書き
込みます。これは、ＤＯＳのワークエリアを書き換えたりすると異常な動作をするため
です。これを、００１０Ｈ番地から０００１Ｈ番地まで、０４１０Ｈ番地から０４０１
Ｈ番地まで、以下、３Ｃ１０Ｈ番地から３Ｃ０１Ｈ番地まで繰り返し、すべての番地で
正常に読み書きできたときには、そのスロットのそのページには、ＲＡＭが存在するこ
とになります。ページ１のＲＡＭの有無を調べるときには４０１０Ｈ番地から同じよう
に調べてください。これは、ＭＳＸマガジン１９８７年９月号に紹介されたアルゴリズ
ムです。なぜ、検索するアドレスが飛び飛びなのかというと、例えば７ＦＦＤＨ番地な
どはディスクインターフェイスのメモリマップドＩ／Ｏなどが使っているためです。ま
た、特定の１バイトにＲＡＭがあっても、そのＲＡＭはソフトが使う特殊なＳ−ＲＡＭ
である場合があります。そこで１６Ｋバイトほぼ全域を検索するようです。また、将来、
Ｓ−ＲＡＭを３２Ｋバイト搭載したゲーム用データ保存カートリッジや音源カートリッ
ジのようなものが、メモリマップドＩ／Ｏでない方式で出てくることも考えられますが、
ソフトの説明書に「余分なＳ−ＲＡＭカートリッジやＲＯＭカートリッジは外しておい
てください」と書いておけばいいでしょう。


<A NAME="BM2_1_3"></A>　　　２．１．３　ＶＤＰ

　ここでは、ＶＤＰを使用する際、特に問題になりがちな機能について簡単に箇条がき
します。
　ＭＳＸ２になってから、ＶＤＰにビットブロックトランスファという、ＶＲＡＭから
メモリやディスクに直接データを転送できる機能がつきました。ただ、ＶＲＡＭと裏Ｒ
ＡＭ間では転送が出来ません。（ＢＩＯＳを使った場合）これは、この機能が使われる
ときは、ＲＯＭが表に出ているためです。ＤＯＳ上でこの機能を使うときは注意してく
ださい。
　ＭＳＸ２ではパレット機能がつきました。ＶＤＰの命令や、ＢＩＯＳのＳＥＴＰＬＴ
で、パレットを変えることが出来ます。ただ、ＢＩＯＳのＳＥＴＰＬＴでパレットを変
更するときは、システムが自動的にパレットテーブルをＶＲＡＭ上の特定のアドレスに
作成します。したがって、ハードウェアスクロールを使うソフトなどが、パレットをＢ
ＩＯＳで書き換えようとすると、画面にゴミが出てしまいます。カラーパレットを変え
るソフトでは、パレット設定はＶＤＰを直接操作して行なってください。この方法につ
いては、「ＭＳＸ２テクニカルハンドブック」１６３ページに掲載されています。
　ＭＳＸ２では、画面を切り替えても画面の初期化は行なわれません。画面の初期化は
ソフトウェア側で行なってください。特に、画面は消しても、スプライトを初期化して
いないために、画面にゴミスプライトが出るソフトがあります。スプライトの初期化は
忘れずにやってください。
　「ＭＳＸ２テクニカルハンドブック」のＶＤＰ関係の追加説明です。２１０ページの
図４．６６で、「R#5　A14 A13 A12 A11 A10　 1　 1　 1」と書いてありますが、本当
はこうでなくて　「R#5　A14 A13 A12 A11 A10　A9　 1　 1」です。ただし、A9には必
ず１を指定しなければなりません。それじゃあ、本と変わらないじゃないか、と思う人
がいるかも知れませんが、全然違います。例えば、R#5に&B11110111を、R#11に&B00000
011を代入したとすると、マニュアルの解釈では、アトリビュートテーブルに&H1F800を
代入するという意味になってしまいますが、実際にはそのような場所にはアトリビュー
トテーブルは作成されず、&H1FA00に作成されます。このあたりはかなり苦しんだ人が大
勢いて、このおかしな動作のために機械語からスプライトを扱うことをあきらめた人を
著者は何人か知っています。もう一か所、この本にはとんでもない間違いがあるのです
が、そちらのほうは第８部のほうを参照してください。


☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆　はみ出しコラム　☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
　この本の初版本にはあまり意味のない情報だけをひたすら並べていたコーナーがあり
ました。第２版では、そのような部分は真っ先に削除されてしまう予定でしたが、少し
は役に立つ情報も載っていたので、このようなはみ出しコラムとして残ることができま
した。何といってもページの余った部分に陣取っているので、長い能書きをたれている
暇がありません。とっとと本文に突入します。（とかいいながら５行も使ってしまった）
　システムワークエリアのＮＥＷＫＥＹ（ＦＢＥ５Ｈ）にはキーボードマトリクスの状
態がそのまま入っているのでキーの情報がリアルタイムで読み込めます。キーボードマ
トリクス表はＭＳＸ２テクニカルハンドブックの２８４ページに載っています。
　ＢＡＳＩＣのプログラムをロードしてからＴＸＴＴＡＢ（Ｆ６７６Ｈ，２）の値＋２、
＋３番地に２５５を書き込むとそのプログラムはＬＩＳＴが取れなくなりますが、普通
に実行できます。ここの２バイトに０を書き込むとＬＩＳＴが取れるようになります。


<A NAME="BM2s"></A>　　 第２章　システムのバグとその回避

　ＭＳＸにはシステムにいくつかのバグがあり、プログラムにバグがないのに正常に動
作しないことがあります。
　ここでは、それらのバグの回避方法について説明します。
　なお、ＲＳ−２３２Ｃのバグについては、第４部を参照してください。


<A NAME="BM2_2_1"></A>　　　　２．２．１　サブＲＯＭコール

　ＭＳＸ２で、ＤＯＳ上からサブＲＯＭをコールすると暴走することがあります。（し
ないこともあります）これは、ＤＯＳのスロット切り換えルーチンにバグがあるためで
す。したがって、ＤＯＳからサブＲＯＭを呼び出すときは、次のような、大変に面倒な
方法を使わなくてはなりません。

●ＤＯＳからサブＲＯＭを呼び出す方法
　１．ページ０のＲＡＭがスロット０の拡張スロットにある場合と、ＭＳＸ２バージョ
　　　ンアップアダプターを使っている場合は、ＤＯＳのＣＡＬＳＬＴ（００１ＣＨ）
　　　ルーチンで直接呼び出します。

　２．そのほかの場合は、スロット切り換えプログラムをページ２かページ３に置いて、
　　　サブＲＯＭを呼び出すときは直接サブＲＯＭを呼び出すのではなく、そのスロッ
　　　ト切り換えプログラム（後述）を呼び出します。

　ページ０のＲＡＭがスロット０の拡張スロットにある場合は、異常動作が起きないた
め、普通にＣＡＬＳＬＴでサブＲＯＭを呼び出せます。また、バージョンアップアダプ
ターでは、ＤＯＳのスロット切り換えのバグの対策が立てられているので、これも普通
にサブＲＯＭが呼び出せます。

　切り換えプログラムの内容ですが、まずページ０をＤＯＳのＥＮＡＳＬＴでメインＲ
ＯＭに切り換え、そこから値をいれてＥＸＴＲＯＭルーチンをコールします。サブＲＯ
Ｍから実行が帰ってきたら、（この時点ではページ０はメインＲＯＭになっている）メ
インＲＯＭのＣＡＬＳＬＴでページ０をＲＡＭに切り換えます。なぜＥＮＡＳＬＴを使
わないかというと、メインＲＯＭのＥＮＡＳＬＴはページ０を切り換えることができな
いためです。（ＤＯＳのＥＮＡＳＬＴはページ０も切り換えることができます）
　この、ページ２またはページ３にスロット切り換えプログラムを置く方法は、スロッ
ト０の拡張スロットにＲＡＭがある場合に暴走しますので、プログラムでは必ず二つの
方法を別々に用意してください。

　このような面倒なことをしなければ、ＤＯＳからサブＲＯＭは呼び出せません。サン
プルプログラムに、ＤＯＳからサブＲＯＭを呼びだすプログラムを用意しておきました
ので、そちらのほうも参考にしてください。なお、こんな面倒な方法は使っていられな
い、という方は、ＤＯＳからはサブＲＯＭは呼びださないか、Ｉ／ＯのＡ８Ｈ番地とＦ
ＦＦＦＨ番地のメモリマップドＩ／Ｏを直接操作してサブＲＯＭを呼びだしてください。
これらのＩ／Ｏポートは、将来にわたっても変更されることはないので、安心して直接
操作することができます。
　なお、ＭＳＸ２＋，turboRでは、異常動作が起きないようなスロット構成をするよう
に決められましたので、安心してサブＲＯＭを直接インタースロットコールできます。


<A NAME="BM2_2_2"></A>　　　　２．２．２　割り込みフック

　ＭＳＸではキー入力やいろいろな処理を割り込みによって処理しています。そして、
割り込みフックを書き変えれば、ユーザーが自分で割り込みを処理できるようにもなっ
ています。（フックの使い方に関しては「ＭＳＸ２テクニカルハンドブック」第２部４
章を参照）ところが、ＤＯＳ上で割り込みフックを使うと、一部の機種では暴走するこ
とがあります。これは、割り込みプログラムをＤＯＳが処理する場合に、一時的にペー
ジ０がメインＲＯＭに切り換わるために、スロット構成によってはうまく切り換えが出
来ないためです。これを回避する方法は次のとおりです。

●ＤＯＳ上でプログラムを組む場合、割り込みプログラムはページ０には置かない。ま
た、割り込みフックにＪＰ命令を置かない（必ずＲＳＴ　３０Ｈでインタースロットコ
ールする）

　この現象も、２．２．１と同じく、ＤＯＳのインタースロットコールルーチンに異常
があるのが主な原因です。異常を起こす機種は、ソニーＨＢ−Ｆ５００、ヤマハＹＩＳ
−８０５などの、ページ０のＲＡＭがスロット０の拡張スロットにある機種です。


<A NAME="BM2_2_3"></A>　　　　２．２．３　メガＲＯＭ

　メガＲＯＭは、ＲＯＭ内部のあるアドレスがメモリマップドＩ／Ｏになっていて、そ
こにＬＤ命令などで値を書き込んで、８Ｋバイトまたは１６Ｋバイトごとにメモリを切
り替えることができるＲＯＭです。最大３２Ｍビットまでのメモリが一本のＲＯＭカー
トリッジの中に納められます。拡張スロットは使っていないため、拡張スロットに差す
ことも出来ます。切り換え方式が何種類かあって、会社ごとにメモリマップドＩ／Ｏの
アドレスや切り換え方が微妙に違います。
　この、メガＲＯＭですが、一部のＭＳＸ１では、動作不良を起こすことが知られてい
ます。この原因ははっきりと調べたわけではないのですが、本体からスロットに信号を
送るときに、一部の機種では特殊な場合に信号をカットしてしまうことがあるためと、
バスのタイミングが機種ごとにかなりばらつきがあるためのようです。これは、ハード
をメーカーに修理に出すほかに回避する方法がありません。また、メガＲＯＭを差すと、
動作はしてもかなり機嫌が悪くなる機種もあります。ＭＳＸ２ではバスのタイミングな
どが統一されているので関係ありません。


<A NAME="BM2_2_4"></A>　　　　２．２．４　Ｔ社の機種のみに現われる現象

　Ｔ社のＭＳＸは、電源をいれてからＢＡＳＩＣが立ち上がるまでの間に、画面に女性
の顔のデジタイズのようなものが一瞬だけ現われることがあります。この場合、その機
械には悪霊が取り憑いていますので、近くの神社でお祓いを受けることが必要になりま
す。（メーカーに修理に出しても、異常なしといわれてしまう）
　これはＴ社の機械だけに現われる現象なので、そのほかの機種では関係ありません。
著者の回りにはＴ社の機械を持っている人物がいないので、直接この現象を確かめたわ
けではないのですが、放っておくとワークエリアが壊されたり、ＶＤＰやＩ／Ｏポート
に出るはずのないデータが出力されたりするようです。


<A NAME="BM2_2_5"></A>　　　　２．２．５　ソフトウェアリセット

　ＭＳＸでは、０番地ジャンプでリセットすると、（ソフトウェアリセットという）漢
字ＲＯＭが使えなくなることがあります。これは、デバイスイネーブル機能が原因とな
っています。
　デバイスイネーブルというのは、バス競合を防ぐための機能です。例えば、内蔵の漢
字ＲＯＭがある機種に、外付けの漢字ＲＯＭを接続すると、同じＩ／Ｏポートに二つの
機器が差さっていることになり、漢字ＲＯＭからの信号が競合して、最悪の場合ＭＳＸ
本体を破壊することがあります。これを防ぐためにＩ／ＯポートのＦ５Ｈ番地に用意さ
れたのがデバイスイネーブルで、これの働きは次のようになっています。
　電源が投入されると、ＢＩＯＳは内蔵の漢字ＲＯＭを切り離した状態で漢字ＲＯＭの
状態を調べます。内蔵の漢字ＲＯＭは切り離されているので、漢字ＲＯＭが存在すれば
それは外付けの漢字ＲＯＭということになります。
　外付けの漢字ＲＯＭがなかった場合、ＭＳＸはＩ／ＯポートのＦ５Ｈ番地のビット０
に１を書き込んで、内蔵の漢字ＲＯＭを有効にします。（「ＭＳＸ２テクニカルハンド
ブック」３９１ページを参照）これによって、漢字ＲＯＭを内蔵した機種でも、外付け
の漢字ＲＯＭを差すことが出来るわけです。ＲＳ−２３２Ｃにも同じような機能があり
ます。
　ところが、プログラムが“ＪＰ　０Ｈ”などで０番地に飛んだときは、内蔵漢字ＲＯ
Ｍが接続された状態で漢字ＲＯＭの状態を調べるルーチンにいってしまいます。すると、
ＭＳＸは内蔵漢字ＲＯＭを外付けだと思って切り離してしまいます。こうして漢字ＲＯ
Ｍが使えなくなるわけです。電源が投入されたときや、リセットボタンが押されたとき
は内蔵漢字ＲＯＭが切り離された状態で外付けのものがあるかどうかを調べるルーチン
に行くので問題はないのですが、プログラムがリセットをかけたいとき、すなわち０番
地ジャンプをするときには、何らかの処置を施さなくてはなりません。具体的には次の
ようにします。

●ソフトウェアがリセットをかけるときは、次のようにする。

　ＬＤ　　Ａ，００Ｈ
　ＯＵＴ　（Ｆ５Ｈ），Ａ
　ＪＰ　　０Ｈ

　もともとＩ／ＯのＦ５Ｈ番地は「ＭＳＸ２テクニカルハンドブック」にも書かれてい
るようにユーザーが読み書きしてはいけないことになっているので、あまりよい方法で
はありませんが、これ以外には回避する方法がありません。ちなみに、この処理を行な
っても動作不良が直らない可能性がありますが、それはその機種ではＩ／ＯのＦ５Ｈ番
地の動作がほかの機種と違うためです。（もともと直接アクセスすることを考えていな
いのでこういうこともありうる）
　なお、ＭＳＸ２＋では、ここに０を書き込めば必ず内蔵のものが切り離されるので、
安心して０を書き込めます。

　また、ＭＳＸ２＋では、リセットの状態を調べることができるようになりました。こ
れには、増設されたＢＩＯＳを使います。

●ＭＳＸ２＋でリセットの状態を調べるには、次のようにする。

　ＣＡＬＬ　０１７ＡＨ

　このとき、返ってきたＡレジスタのビット７が立っていれば”ＪＰ　０Ｈ”でのリセ
ット（ソフトウェアリセット）で起動されたと分かります。このビットが立っていなけ
ればハードウェアリセットです。ソフトのほうがハードウェアリセットかソフトウェア
リセットか調べられないといろいろと不都合が生じるので、このような機能が増設され
たようです。実際には、Ｉ／ＯのＦ４Ｈ番地にリセットを調べるハードが追加されて、
このＢＩＯＳの内部では、そこを読み書きしています。
　この機能を安全に使用するためには、リセットをかけるソフトウェア側であらかじめ
ここに値を書き込んでおく必要があります。それにも、ＭＳＸ２＋になって新たに追加
されたＢＩＯＳを使用します。

●ＭＳＸ２＋でリセットするときは、次のようにする。
　ＣＡＬＬ　０１７ＡＨ　　　　　’現在のリセットの状態をＡレジスタに書き込む
　ＯＲ　　　８０Ｈ　　　　　　　’リセットフラグをセットする
　ＣＡＬＬ　０１７ＤＨ　　　　　’新たな値を書き込む
　ＪＰ　　　０Ｈ　　　　　　　　’０番地ジャンプ

　ちなみに、ＭＳＸ２＋より前の機種ではソフトウェアリセットとハードウェアリセツ
トを区別する方法はありません。


<A NAME="BM2_2_6"></A>　　　　２．２．６　汎用Ｉ／Ｏポート

　ＭＳＸでは、汎用Ｉ／Ｏポート１にマウスを差したままＰＡＤ（０）関数を呼び出す
か、ポート２にマウスを差してＰＡＤ（４）を呼び出すと、システムが停止してしまい
ます。これを回避する方法は以下のとおりです。

●マウスをポートから抜く


<A NAME="BM2_2_7"></A>　　　　２．２．７　算術演算ルーチンＭＡＴＨ−ＰＡＣＫ

　算術演算ルーチン群MATH-PACKは、ページ０及び１がメインＲＯＭであることを期待し
てプログラムされているので、ＤＯＳ上から使用しようとすると動作しません。ＤＯＳ
上からMATH-PACKを使用する場合は、次のルーチンを必ず組み込んでおいてください。

          ORG  406FH                          ORG  5597H
          LD   IX,406FH                GETYPR:LD   A,(0F663H)
          JP   0159H                          CP   8
          ORG  4666H                          JR   NC,DOUBLE
          LD   IX,4666H                       SUB  3
          JP   0159H                          OR   A
          ORG  4EB8H                          SCF
          LD   IX,4EB8H                       RET
          JP   0159H                   DOUBLE:SUB  3
          ORG  5439H                          OR   A
          LD   IX,5439H                       RET
          JP   0159H                          ORG  66A7H
                                              POP  AF
                                              RET


☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆　はみ出しコラム　☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
　ＢＡＳＩＣのプログラム中に、０が２バイト続くようなデータを書き込むと、そこか
らあとの行はＬＩＳＴが出なくなります。
　ＰＣ−９８シリーズで２ＤＤフォーマットしたディスクをＭＳＸで読もうとすると、
うまく読めないことがあります。９８とＭＳＸでディスクを共用するときにはＭＳＸで
フォーマットしたほうが安全です。９８は通常８セクターフォーマットを、ＭＳＸは９
セクターを使うのでうまく読めないと思う人もいるかも知れませんが、実はどちらの機
種も両方のディスクを読み書きできるように設計されているので困りません。
　ディスクファイルのディレクトリーエリアのタイムスタンプの日付の部分の所を全部
０で埋めると、ディレクトリーを取ったときタイムスタンプが出なくなります。
　ディスクのＦＡＴ中にＦＦ８Ｈ〜ＦＦＦＨのいずれかの値があったら、そこがファイ
ルの終了クラスタであるということを意味します。ＦＦ７Ｈならばそのクラスタは不良
クラクタで、以後そのクラスタは使用されません。
　ＭＳＸ，ＭＳＸ２では、自分自身をページ１またはページ２のＲＡＭに転送し、あた
かもそこがＲＯＭカートリッジであるかのように振る舞うソフトを起動すると、次に電
源を入れたときに、システムがＲＡＭに残っている内容を見てそれがＲＯＭカートリッ
ジであると誤認してしまうことがあります。そうなった場合、何度リセットしてもその
ソフトが必ず起動してしまい、システムが起動しなくなることがあります。このような
場合は、一旦電源を切り、コンセントを外して、さらに内蔵タイマー用の電池を外して
２０分程度放っておくと、ＲＡＭの内容が消失して再びシステムが起動できるようにな
ります。なお、ＭＳＸ２＋以降の機種は、システムが起動時にＲＡＭに書かれた内容を
ＲＡＭと間違えないように、ＲＡＭの内容を消去するので、この異常動作は起こりませ
ん。具体的には、ＲＡＭに書かれたＲＯＭ ＩＤの内容を消去しています。
　インタースロットコールから戻ってきたとき、ＭＳＸ１では割り込みは禁止されてい
ますが、ＭＳＸ２以降の機種では割り込みはコール前の状態になっていることになって
います。しかし、まれにＥＩ状態でインタースロットコールしたのにＤＩ状態で戻って
くることがあります。これは、Ｚ８０ＣＰＵの特性によるものです。ＥＩである必要の
あるソフトは、インタースロットコール直後にＥＩしておいたほうが安全です。
　ＭＳＸでは、今まで、Ｉ／Ｏポートは８ビットとして使用してきましたが、実は、仕
様上、１６ビットＩ／Ｏポートを使用しても構わないということが判明しました。現在
は存在しませんが、後々１６ビットＩ／Ｏを使用したハードが登場する可能性がありま
す。


☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆　はみ出しコラム　☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
　ＭＳＸ２，ＶＲＡＭ６４Ｋの機種は、ほとんどの市販ソフトが動かないのでとても淋
しいのですが、日立と東芝の機械はメーカーが１２８Ｋ拡張サービスをやってくれてい
たので、ありがたや、市販ソフトが動くようになります。たまに、ＶＲＡＭ１２８Ｋ用
のソフトが「日立ＭＢ−Ｈ３、東芝ＨＸ−２３では動作しません」などと書いているの
をみて変だな、と思った鋭い人がいるかも知れませんが、そういうわけなのです。キヤ
ノンや三洋もＶＲＡＭ６４Ｋの機械を出していましたが、こちらがバージョンアップサ
ービスをしていたかどうかはわかりません。でも、半田ごてがあれば割りと簡単に拡張
できます。
　漢字コード２２２ＦＨ〜２２７ＦＨ、２３２０Ｈ〜２３２ＦＨまでのコード（特殊記
号）は、機種によって違う場合があるので注意してください。ＭＺなどの機種では、全
然違う記号がここのコードに割り当てられています。
　ＢＡＳＩＣのＰＵＴ　ＫＡＮＪＩやＢＩＯＳのＫＮＪＰＲＴで漢字を表示する前に、
ＰＳＥＴ命令で点を打てば、そこが始点になります。（ＯＰＥＮ”ＧＲＰ：”で文字を
表示するときと同じです）
　メモリマッパの説明がよく分からなかったかも知れないので、改めて詳しく解説しま
す。メモリマッパ内蔵機にマッパＲＡＭ拡張カートリッジ（具体的にはＤＯＳ２カート
リッジ）を差すと、Ｉ／ＯのＦＣＨからＦＦＨ番地には２つの機器が差さっていること
になります。ここで、たとえばＦＤＨに値を書き込むと、内蔵、外付けの両方のメモリ
マッパに信号が伝わり、両方のマッパが切り換わります。もちろん、両方とも自分のス
ロットのＲＡＭだけを切り換えます。こういうことができるという恐ろしい仕様になっ
ているのです。ＤＯＳ２のマッパは標準のマッパとは仕様が違う、というような報道が
されたことがありますが、仕様自体は同じです。ただし、システムが自分用に３２Ｋの
領域を確保することと、上に述べた２つの機器が同時に接続されている場合を予期して
プログラムを組まないと、マッパ対応にしても、ＤＯＳ２では動作しません。ＦＣＨ〜
ＦＦＨのＩ／Ｏから値を読むことができないのも、一度に２つの機器が接続されている
ことがあるためです。（ＭＳＸでは、１つのポートに２つの機器が接続されている場合、
そのポートから値を読むと異常な動作をする）なお、最高８つまでのマッパＲＡＭを同
時に接続できることになっています。ちなみに、通常のコンピューターは２つの機器が
同時に同じポートに接続されている、などということは絶対にありえないように設計す
るのが普通です。１つのポートに８つまでの機器が並列につながる、というのは尋常で
はありません。
　それで思い出しましたが、ＤＯＳ２の２５６ＫＲＡＭ内蔵版を２つ差すと、５１２Ｋ
で立ち上がります。マッパ内蔵機ではもっとＲＡＭが増えます。
　ＭＳＸ２＋では、ＶＤＰがまだ前の処理を終えていないときにＶＤＰをアクセスする
と、ＶＤＰからウェイト信号が来て、その間実行が停止します。turboRでは、８μ秒以
内の間隔でＶＤＰをアクセスするとシステムのほうが自動的にＣＰＵにウェイトをかけ
るようになっています。なお、これらの保護機能はＭＳＸ，ＭＳＸ２には付いていませ
ん。あまりＶＤＰを酷使すると、異常動作を起こすことがあるので、少しばかり注意が
必要です。
　アスキーのＭＳＸ−Ｖｉｅｗ用のソフトは、Ｃ言語を使ってアプリケーションを組も
うと思っても、ＭＳ−ＤＯＳ上で動くＣを使わなければ組めませんでしたが、ようやく
ＭＳＸ−Ｃで組むためのソフトが開発されたようです。ＭＳＸ−Ｄａｔａｐａｃｋ　ｔ
ｕｒｂｏＲ版のユーザーには無償でディスクの書き換えサービスを行なっているようで
す。ので、興味のある方はアスキー社まで問い合わせるといいかもしれません。
　ＭＳＸ−ＤＯＳ２　ＴＯＯＬＳのファイルの内容は、出荷時期により相当変わってい
ます。これもアスキーに問い合わせないと最新版は手に入りません。
　付属サンプルプログラムディスクに収録されていて、第７部では触れられていないソ
フトの紹介をちょっとします。これはＳＲＡＭＶＪＥという名前で、アスキー、松下の
ＭＳＸ−ＪＥ用の内蔵ＳＲＡＭをディスクファイルに保存するソフトです。松下の機種
は、どうもＳＲＡＭが消えやすい機種があるようなので、そういう機種をお持ちの方は
ご利用ください。名前のとおりＳＲＡＭのアスキー、松下版です。
　メインＲＯＭの０００４Ｈ番地から２バイトにフォントの先頭アドレスが入っていま
す。ワークエリアのＣＧＰＮＴ（Ｆ９１ＦＨ，３）には、フォントのあるスロット番号
と開始アドレスが入っていますが、ここを書き換えたあともとに戻すときはこの値を参
考にすると面倒がなくていいです。ワークエリアを２バイト節約することができます。
　ＤＯＳからＢＡＳＩＣにいって、ＣＡＬＬ　ＫＡＮＪＩで漢字ドライバを起動し、Ｃ
ＡＬＬ　ＳＹＳＴＥＭでＤＯＳに戻ります。すると、ＴＹＰＥコマンドで漢字ファイル
が読めるようになります。ただ、この状態からＭＥＤなどを起動させると暴走してしま
います。たぶんＭＥＤがＶＲＡＭを直接いじっているのでしょう。
　アスキー社製ハードディスクインターフェイスを接続した状態でマスタースロットの
４０２９Ｈ番地をコールすると、ハードディスクのシッピングを行います。ソフトでシ
ッピングを行いたいときに使用してください。


<A NAME="BM3s"></A>　　　第３章　メモリマッパ


<A NAME="BM2_3_1"></A>　　　　２．３．１　メモリマッパ概要

　ＭＳＸ２では、Ｉ／ＯポートのＦＣＨ番地からＦＦＨ番地までをメモリマッパに割り
当てています。これは、ＲＡＭをページごとに（１６Ｋごとに）一瞬にして切り換えて
しまうという機能です。ただし、標準仕様ではないので、機種によってはこの機能がな
い場合もあります。メモリマッパがあるかどうかは、次の方法で調べられます。

　ＢＡＳＩＣから　ＯＵＴ　２５５，１　を実行する
　暴走すれば、メモリマッパがある。

　本体ＲＡＭ１２８Ｋバイト以上の機種には、必ずついています。また、ＭＳＸ２＋で
はすべての機種についているようです。
　使い方としては、Ｉ／ＯのＦＣＨ番地がページ０の、ＦＤＨがページ１の、ＦＥＨが
ページ２の、ＦＦＨがページ３のＲＡＭの切り換えに使われています。
　システムは、リセット時に、ＦＣＨ番地に３を、ＦＤＨに２を、ＦＥＨに１を、ＦＦ
Ｈに０を書き込みます。そして、ページ０に３番の、以下、ページ１に２番、ページ２
に１番、ページ３に０番のＲＡＭがそれぞれ割り当てられます。（ＲＡＭはすべて１６
Ｋごと）ここで、例えばＦＤＨに０を出力したとします。すると、ページ１のＲＡＭが
一瞬にしてページ３と同じ０番のＲＡＭに切り換わってしまいます。ここで、ＲＡＭの
５０００Ｈ番地に値を書き込むと、同時にＤ０００Ｈ番地の内容も書き変わってしまい
ます。先ほどの、メモリマッパがあるかどうかを調べる方法は、ページ３のＲＡＭを切
り換えるということなので、その結果ワークエリアが消失して暴走するわけです。メモ
リマッパがない機種では、元々Ｉ／ＯのＦＦＨ番地には何もつながっていないので、何
も変化がなく実行が返ります。
　メインＲＡＭ６４Ｋの機種では、１６ＫのＲＡＭを４個しか持っていないので、この
くらいしか利用価値がありませんが、ＲＡＭ１２８Ｋの機種では、ＲＡＭの番号に０か
ら７までが指定できます。２５６Ｋの機種では０から１５までが指定できます。そこで、
普段は隠れていて見えないＲＡＭをデータエリアに使ったりすることができます。
　以下にスロット３−１にＲＡＭがある場合について例を図示します。

　 ＳＬＯＴ　３−１　　　　 　　３−１　　　　　　３−１

　 ページ0　ＲＡＭ３番　　　　ＲＡＭ３番　　　　ＲＡＭ５番
　 ページ1　ＲＡＭ２番　　　　ＲＡＭ０番　　　　ＲＡＭ０番
　 ページ2　ＲＡＭ１番　　　　ＲＡＭ１番　　　　ＲＡＭ１番
　 ページ3　ＲＡＭ０番　　　　ＲＡＭ０番　　　　ＲＡＭ０番

　　　　　　電源投入時　　　　OUT 0FDH,0を　　　 RAM128K以上の機種でさらに
　　　　　　　　　　　　　　　実行したとき　　　 OUT 0FCH,5を実行したとき

　本体ＲＡＭがいくらあるのかを調べるにはひたすらＲＡＭを切り換えながらデータを
書き込んで、ちゃんと読み込めるかどうかをチェックしていくという大変に原始的な方
法を使ってください。（ＭＳＸ２＋の起動時にも、この方法が使われています）ＦＣＨ
〜ＦＦＨから値を読み込むという方法もありますが、この方法を使うと、ＤＯＳ２カー
トリッジなどのマッパＲＡＭ拡張カートリッジを接続した場合にバス競合が起こって本
体を破壊する恐れがあるので、これらのＩ／Ｏポートから値を読み込むのは絶対に避け
てください。（バス競合は読み込むときだけ起こるので、書き込みはしても大丈夫です）

　以上がメモリマッパの使い方ですが、これではもともとメモリマッパがない機種では
マッパが使えません。また、ＲＡＭのＩ／Ｏバスが直接ＣＰＵに接続されている必要が
あります。つまり、６４Ｋ増設ＲＡＭカートリッジなどを接続しても、マッパＲＡＭは
増えないのです。そこで、ＤＯＳ２カートリッジなどでは内蔵ＲＡＭに直接ＦＣＨ〜Ｆ
ＦＨ番地のＩ／Ｏがつながっています。これは普通のマッパと同じ使い方もできますが、
最後の２つのＲＡＭ（ＲＡＭ１２８Ｋの機種なら６番と７番、２５６Ｋの機種なら１４
番と１５番）は、ＤＯＳ２システムが使っているので、ここをユーザープログラムが使
おうとすると暴走します。また、そうやって拡張していくと、ユーザープログラムの負
担がかなり重くなるので、ＤＯＳ２には拡張ＢＩＯＳでＲＡＭを切り替える方法が用意
され、こちらを使用してマッパＲＡＭを操作することが推奨されています。この拡張Ｂ
ＩＯＳコールを用いたマッパＲＡＭの使い方については、次の第２節を参照してくださ
い。


<A NAME="BM2_3_2"></A>　　　　２．３．２　メモリマッパ拡張ＢＩＯＳ

　ＭＳＸで６４Ｋバイトを越えるＲＡＭを使用するときは、Ｉ／ＯのＦＣＨ〜ＦＦＨ番
地のメモリマッパ用のＩ／Ｏを使って切り換えます。しかし、この方式を使うと、若干
の問題が出てきます。具体的には、次のようなものです。
　１．ユーザープログラムがＲＡＭの容量を調べるのが難しい
　２．メモリマッパを使用したプログラムを二つ以上同時に使用しようとすると、使用
するセグメントが衝突して動作しないことがある
　ユーザープログラムがＲＡＭ容量を調べようとした場合、ひたすらセグメントを切り
換えながらその番号のセグメントがあるかどうか調べるという原始的な方法を取らざる
をえません。これはかなり面倒な方法であり、暴走の危険も生じます。
　そこで、マッパＲＡＭを管理するための拡張ＢＩＯＳが用意されました。これを使っ
てＲＡＭを管理することにより、マッパを使うプログラムを同時に実行することができ
ます。また、セグメント数の計算や、プログラムごとのセグメントの割り付けもマッパ
ＢＩＯＳがやってくれますので、ユーザー側の負担が大幅に軽減されます。
　現在、ＤＯＳ２がこのメモリマッパ拡張ＢＩＯＳを内蔵しています。ＤＯＳ２では動
作するのに最低３２ＫバイトのワークＲＡＭを必要とするためです。ＤＯＳ２上で動か
すことが明らかなソフトは、メモリマッパは直接Ｉ／Ｏ切り換えでなく、拡張ＢＩＯＳ
を使用してください。ＤＯＳ２の利用するセグメントをうっかり使用したりすると暴走
します。

　　　マッパテーブルの呼び出し方法

　メモリマッパ拡張ＢＩＯＳは、常にページ３に置かれ、いくつのマッパＲＡＭが接続
されていて、いくつのセグメントが使用できるのか、という内容が保存されているマッ
パテーブルも、やはりページ３に常に存在しています。マッパテーブルがどこにあるの
かを調べるには、第２部第７章で紹介したＦＦＣＡＨ番地コールを使用します。ＦＢ２
０Ｈ番地のビット０を見て拡張ＢＩＯＳコールが可能かどうかチェックしてから、次の
方法で調べてください。

●マッパテーブルの先頭アドレスを得る方法
　Ａレジスタに０、Ｄレジススタに４、Ｅレジスタに１を入れてＦＦＣＡＨ番地をコー
ルする
　戻ってきたＡにプライマリマッパのスロット番号（システムが使用しているメインＲ
ＡＭのスロット番号）、ＨＬにマッパテーブルの先頭アドレスが返る。ＤＥは保存され
る。裏レジスタ及びＩＸ，ＩＹレジスタは破壊される
　もし、戻ってきたＡの値が０だったら、メモリマッパ拡張ＢＩＯＳは存在しない
　マッパテーブルの内容は以下のとおりです。


　アドレス　内容　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　
　　ＨＬ+0　マッパスロットのスロット番号　　　　　　　　　（複数のマッパＲＡＭが
　　　　+1　16KバイトRAMセグメントの総数（1〜255）　　　　　存在する場合、先頭は
　　　　+2　未使用の16KRAMセグメントの数　　　　　　　　　　プライマリマッパにな
　　　　+3　システムに割り当てられた16KRAMセグメントの数　　る。セグメントの数は
　　　　+4　ユーザーに割り当てられた16KRAMセグメントの数　　一つのマッパＲＡＭに
　　+5〜+7　現在未使用。予約　　　　　　　　　　　　　　　　1〜255まで）
　　+8〜　　他のマッパのスロット番号。ない場合+8は０　　　　　　　　　　　　　　

　マッパサポートルーチンを使用するには、ページ３の特定のアドレスをコールします。
その番地は不定なので、以下の方法で調べる必要があります。

●マッパサポートルーチンの先頭アドレスを得る方法
　Ａに０、Ｄに４、Ｅに２を入れてＦＦＣＡＨ番地をコールする
　戻ってきたＡにプライマリマッパの総セグメント数、Ｂにプライマリマッパのスロッ
ト番号、Ｃにプライマリマッパの未使用セグメント数、ＨＬにジャンプテーブルの先頭
アドレスが返る。ＤＥは保存される。裏レジスタ及びインデックスレジスタは破壊され
る
　マッパサポートルーチンはジャンプテーブルになっており、その内容は以下のとおり
です。


　アドレス　エントリ名　機能　　　　　　　　　　　　　　　　　　　　　　　　　　

　 ＨＬ+0H　ALL_SEG　　 16Kのセグメントを割り付ける
　　　 +3H　FRE_SEG　　 16Kのセグメントを開放する
　　　 +6H　RD_SEG　　　セグメント番号Ａの番地ＨＬの内容を読む
　　　 +9H　WR_SEG　　　セグメント番号Ａの番地ＨＬにＥの値を書く
　　　 +CH　CAL_SEG　　 インターセグメントコール（インデックスレジスタ）
　　　 +FH　CALLS　　　 インターセグメントコール（インラインパラメーター）
　　　+12H　PUT_PH　　　Ｈレジスタの上位２ビットのページを切り換える
　　　+15H　GET_PH　　　Ｈレジスタの上位２ビットのページのセグメント番号を得る
　　　+18H　PUT_P0　　　ページ０のセグメントを切り換える
　　　+1BH　GET_P0　　　ページ０の現在のセグメント番号を得る
　　　+1EH　PUT_P1　　　ページ１のセグメントを切り換える
　　　+21H　GET_P1　　　ページ１の現在のセグメント番号を得る
　　　+24H　PUT_P2　　　ページ２のセグメントを切り換える
　　　+27H　GET_P2　　　ページ２の現在のセグメント番号を得る
　　　+2AH　PUT_P3　　　何もせずに戻る
　　　+2DH　GET_P3　　　ページ３の現在のセグメント番号を得る


　　　マッパサポートルーチンの使用方法

　プログラムはマッパＲＡＭを使用する場合、まず、ＡＬＬ＿ＳＥＧを使って自分用の
セグメントを確保しなければなりません。そうしないと、他のプログラムと使用するセ
グメントが衝突して、暴走する可能性があります。割り付けには、ユーザーセグメント
として割り付ける方法と、システムセグメントとして割り当てる方法があります。ユー
ザーセグメントは、プログラムが終了すると自動的に開放されますが、システムセグメ
ントはＦＲＥ＿ＳＥＧで開放しないかぎり開放されません。通常のプログラムはユーザ
ーセグメントとして割り付けるのが良いでしょう。システムセグメントは、プログラム
が終了したとき次のプログラムにデータを引き渡す場合や、後で再び起動したときのた
めに前のデータを保存しておきたい場合などに使用します。ＤＯＳ２が使うワークＲＡ
Ｍなどは、システムセグメントとして割り付けられています。プログラムは、解放した
セグメントを使用し続けてはなりません。
　なお、これら二つのルーチンを使用する場合、スタックはページ１またはページ３に
置かなければなりません。

●ＡＬＬ＿ＳＥＧ　（セグメントを割り付ける）
　　　入力　Ａ：０ならユーザーセグメントとして割り付け
　　　　　　　　１ならシステムセグメントとして割り付け
　　　　　　　　Ｂ：０ならプライマリマッパに割り付ける
　　　　　　　　０以外は複数マッパの場合の割り付け
　　　　　　　　FxxxSSPPの形でスロット番号を指定する。bit6〜4は以下の割り付け方
　　　　　　　　法の指定に使用する
　　　　　　　　xxxが000のとき：指定スロットのみ割り付け
　　　　　　　　xxxが001のとき：指定のスロット以外で割り付け
　　　　　　　　xxxが010のとき：指定のスロットで割り付けを試み、
　　　　　　　　失敗の場合、あれば他のスロットで割り付ける
　　　　　　　　xxxが011のとき：指定のスロット以外で割り付けを試み、
　　　　　　　　失敗の場合は指定のスロットで割り付ける
　　　出力　Ｃｙ，セットなら未使用セグメントがない
　　　　　　　　　リセットなら割り付けに成功
　　　　　　Ａに割り付けられたセグメント番号
　　　　　　Ｂにマッパスロットのスロット番号（入力でＢ＝０だった場合は０）

●ＦＲＥ＿ＳＥＧ　（セグメントを開放する）
　　　入力　Ａに開放するセグメント番号
　　　　　　Ｂ：０ならばプライマリマッパ
　　　　　　　　０以外ならマッパのスロット番号
　　　出力　Ｃｙ，セットなら失敗
　　　　　　　　　リセットなら成功

　マッパＲＡＭの値を読み書きするには、次のＲＤ＿ＳＥＧ，ＷＲ＿ＳＥＧを使用しま
す。動作速度を維持するために、セグメント番号が有効かどうかのチェックは行われま
せん。指定セグメントが存在するかどうかのチェックはユーザープログラムの責任にな
ります。
　マッパサポートルーチンはページ２を使用して読み書きするため、スタックをページ
２に置くことはできません。また、ページ２は読み書きするマッパスロットに切り換え
ておいてからコールしなければなりません。動作速度を維持するために、マッパサポー
トルーチンがスロット切り換えを行わないためです。ＡＦ以外のレジスタは保存されま
す。割り込みは禁止されて戻ります。ＨＬレジスタで指定されるアドレスの上位２ビッ
トは無効です。セグメントが１６Ｋバイト単位で扱われるからです。

●ＲＤ＿ＳＥＧ　　（指定セグメントから値を読む）
　　　入力　Ａに読み出すセグメント番号
　　　　　　ＨＬにセグメント内のアドレス（上位２ビットは無効）
　　　出力　Ａに指定アドレスの値
　レジスタ　Ｆ？

●ＷＲ＿ＳＥＧ　　（指定セグメントに値を書く）
　　　入力　Ａに書き込むセグメント番号
　　　　　　ＨＬにセグメント内のアドレス（上位２ビットは無効）
　　　出力　なし
　レジスタ　ＡＦ

　セグメント内に機械語プログラムを置いて、ちょうどＭＳＸシステムのインタースロ
ットコールのように、インターセグメントコールすることができます。使い方もインタ
ースロットコールと似ています。インターセグメントコールには、以下に挙げるＣＡＬ
＿ＳＥＧ，ＣＡＬＬＳの二つのルーチンが用意されています。
　これらのルーチンを使用する場合、指定セグメントが存在するかどうかのチェックは
行われません。これは、動作速度を維持するためです。また、コールする前に指定ペー
ジを使用するマッパＲＡＭのスロットに切り換えておくのもユーザープログラムの責任
になります。
　ページ３へのインターセグメントコールは実行することができません。もし指定した
場合、単に指定アドレスがコールされます。ページ０をコールする場合割り込みルーチ
ンなどのエントリーがあるので、コールは慎重に行う必要があります。
　この二つのルーチンは、割り込みの状態を変化させません。従って、コールされたル
ーチンが割り込みの状態を変化させない限り、呼び出し時と同じ状態で戻ります。
　この二つのルーチンは、裏レジスタ及びインデックスレジスタを内部で使用します。
従って、これらのレジスタを使ってコール先にパラメーターを受け渡すことはできませ
ん。

●ＣＡＬ＿ＳＥＧ　（インターセグメントコール）
　　　入力　ＩＹの上位８ビットでセグメント番号を指定
　　　　　　ＩＸでコールするアドレスを指定（上位２ビットでページを指定）
　　　　　　ＡＦ，ＢＣ，ＤＥ，ＨＬがコールされたルーチンに渡される
　　　　　　裏レジスタ及びインデックスレジスタは破壊される
　　　出力　ＡＦ，ＢＣ，ＤＥ，ＨＬ，ＩＸ，ＩＹがコールされたルーチンから返される
　　　　　　裏レジスタは破壊される

●ＣＡＬＬＳ　　　　（インターセグメントコール・インラインパラメーター）
　　　入力　ＡＦ，ＢＣ，ＤＥ，ＨＬがコールされたルーチンに渡される
　　　　　　裏レジスタ及びインデックスレジスタは破壊される
　コール手順：　ＣＡＬＬ　ＣＡＬＬＳ
　　　　　　　　ＤＢ　　　セグメント番号
　　　　　　　　ＤＷ　　　コールするアドレス
　　　出力　ＡＦ，ＢＣ，ＤＥ，ＨＬ，ＩＸ，ＩＹがコールされたルーチンから返される
　　　　　　裏レジスタは破壊される

　上に挙げたルーチンの他、直接セグメントの状態を切り換えてしまうルーチンが用意
されています。連続してセグメントを読み書きしたり、他のセグメントにあるデータを
転送せずにそのまま使用する場合などに利用します。これらのルーチンは高速なのでプ
ログラムの効率に影響することはありません。（と、アスキーは言っている）
　これらの直接セグメント切り換えルーチン（ダイレクトページングルーチン）は、指
定されたセグメントが存在するかどうかのチェックは行いません。指定セグメントが存
在するかどうかのチェックはユーザープログラムの責任になります。
　ＰＵＴルーチンは、セグメントを切り換え、同時にメモリ上に書き込んだ値を保存し
ます。ＧＥＴルーチンは、現在のマッパセグメントの状態を返すルーチンで、ＰＵＴル
ーチンでメモリ上に記録された値が返され、Ｉ／Ｏから値を読むことはしません。これ
は、マッパＲＡＭが複数存在する場合、Ｉ／Ｏから値を読むことによってバス競合が起
こる可能性があるためです。従って、ＤＯＳ２上で動くプログラムや、メモリマッパ拡
張ＢＩＯＳを使用しているプログラムは、Ｉ／ＯのＦＣＨ〜ＦＦＨを直接使用してセグ
メントを切り換えてはなりません。
　ＰＵＴ＿Ｐ３ルーチンは、存在はしますが、実際にはマッパを切り換えずに、何もせ
ずに戻ります。これは、ページ３を切り換えると暴走するためです。
　プログラムはこれらのルーチンでセグメントを切り換える前に、現在のセグメントの
状態を保存しておき、プログラム終了時には必ず元の状態に戻す必要があります。プロ
グラムが起動したときに、セグメントの状態が常に同じとは限らないからです。
　ＰＵＴ＿ＰＨ，ＧＥＴ＿ＰＨは、ＨＬレジスタに何らかのアドレスを入れ、その上位
２ビットでページを指定するとき有用なルーチンです。

●ＰＵＴ＿Ｐｎ　　（ページｎのセグメントを切り換える）
　　　入力　ｎはページ番号（０〜３）
　　　　　　Ａにセグメント番号
　　　出力　なし
　レジスタ　なし

●ＧＥＴ＿Ｐｎ　　（ページｎのセグメントの状態を得る）
　　　入力　ｎはページ番号（０〜３）
　　　出力　Ａにセグメント番号
　レジスタ　なし

●ＰＵＴ＿ＰＨ　　（セグメント切り換え・Ｈの上位２ビットでページを指定）
　　　入力　Ｈの上位２ビットでページを指定
　　　　　　Ａにセグメント番号
　　　出力　なし
　レジスタ　なし

●ＧＥＴ＿ＰＨ　　（セグメントの状態を得る・Ｈの上位２ビットでページを指定）
　　　入力　Ｈの上位２ビットでページを指定（ページ３を指定しても無効になる）
　　　出力　Ａにセグメント番号
　レジスタ　なし

　ＤＯＳ２カートリッジに搭載されているものと、turboRに搭載されているものでは、
マッパＢＩＯＳの動作が若干異なります。例えば、ＤＯＳ２カートリッジ版では最も容
量が大きくて最もスロット番号の若いマッパがプライマリマッパになりますが、turboR
では必ず内蔵ＲＡＭがプライマリマッパになります。


<A NAME="BM4s"></A>　　　第４章　漢字ＲＯＭ

　ここでは、主に、漢字ＲＯＭのアクセスの仕方について説明します。


<A NAME="BM2_4_1"></A>　　　　２．４．１　漢字ＲＯＭ入出力

　ＭＳＸで漢字ＲＯＭを操作するときは、直接Ｉ／ＯのＤ８ＨからＤＢＨまでをアクセ
スします。
　漢字のフォント・データを読みだすには、漢字コードと呼ばれる１２ビットのデータ
を使います。これは、ＪＩＳコードや区点コードとは別物ですので、まず目的の漢字コ
ードを求める必要があります。

●漢字コードの求め方
　漢字のＪＩＳコードの上位バイトから３２を引いた値を区、下位バイトから３２を引
いた値を点と呼びます。（これが、いわゆる区点コードです）
　第一水準の場合、区が１５以下なら、（区＊９６＋点）が漢字コードになります。区
が１６以上なら、（区＊９６＋点−５１２）が漢字コードになります。
　第二水準の場合、（（区−４８）＊９６＋点）が漢字コードになります。

　次に、求めた漢字コードを元にＩ／Ｏポートをアクセスします。第一水準と第二水準
で読み出し方が違いますので、順に説明しましょう。

●第一水準漢字を読みだす場合
　Ｉ／ＯポートのＤ８Ｈ番地に漢字コードの下位６ビットを、Ｄ９Ｈ番地に上位６ビッ
トを出力します。そして、Ｄ９Ｈ番地から３２回連続して値を読み込むと、それがその
漢字のフォントになります。

●第二水準の場合は、Ｉ／ＯポートのＤＡＨ番地に漢字コードの下位６ビットを、ＤＢ
Ｈ番地に上位６ビットを出力します。そして、ＤＢＨ番地から連続して３２回読み込み
ます。これが漢字フォントになります。

　フォントの並びは、まず左上に８バイト並べて、次に右上に８バイト並べます。次に
左下に８バイト、右下に８バイトという順番になります。

 データ列　　　　　　　　　　フォント
　１番目　　　　　　　　　　　１番目　　　　　　　　　　９番目
　　：　　　　Ａ　　　　　　　　：　　　　　　　　　　　　：
　９番目　　　　　　　　　　　　：　　　Ａ　　　Ｂ　　　　：
　　：　　　　Ｂ　　　　　　　８番目　　　　　　　　　１６番目
１７番目　　　　　　　　　　１７番目　　　　　　　　　２５番目
　　：　　　　Ｃ　　　　　　　　：　　　　　　　　　　　　：
２５番目　　　　　　　　　　　　：　　　Ｃ　　　Ｄ　　　　：
　　：　　　　Ｄ　　　　　　２４番目　　　　　　　　　３２番目
３２番目

　ＭＳＸでは、通常、Ｉ／Ｏポートへの直接入出力は禁じられています。しかし、漢字
ＲＯＭではほかに方法がありません。ＭＳＸ２になってから追加されたＢＡＳＩＣのＰ
ＵＴ　ＫＡＮＪＩ命令やＢＩＯＳのＫＮＪＰＲＴは、第一水準しかサポートしていない
上に、（ＭＳＸ２＋では第二水準もサポートしています）画面に表示するだけなので、
漢字フォントを直接いじりたいとき、例えば、１６＊１６ドットのフォントを１２＊１
６ドットに圧縮したいときや、漢字フォントをプリンターに直接ビットイメージ印字し
たいときに使えません。また、スクリーン２や４のモードをサポートしていません。そ
れにＭＳＸ１では、漢字ＲＯＭをアクセスするためのＢＩＯＳが用意されていません。
そんなわけで、漢字ＲＯＭのアクセスについては、Ｉ／Ｏポートを直接操作しているわ
けです。
　なお、御存知の方も多いと思いますが、漢字ＲＯＭの空白部分をアクセスすると、空
白ではなく、関係ない文字のフォントが返ってきます。全角のスペースはＪＩＳコード
の２１２１Ｈを使うようにしてください。半角文字については、ＪＩＳコードの２０２
１Ｈ〜２０７ＥＨ、２９２１Ｈ〜２９５ＦＨのフォントの左半分だけを使います。ただ
し、これらの半角フォントは漢字ドライバやＰＵＴ　ＫＡＮＪＩ命令ではサポートして
いません。


<A NAME="BM2_4_2"></A>　　　　２．４．２　　漢字ＲＯＭの存在の有無

　漢字ＲＯＭがないのに漢字入出力を行なおうとすると、画面に豆腐（１６＊１６ドッ
トの四角のこと）が現われてとても悲しい目に合います。そこで、漢字ＲＯＭの存在の
有無を確認することが必要になってきます。
　
●第一水準漢字ＲＯＭが存在するかどうかを確かめる方法
　漢字ＲＯＭのＪＩＳコード２１４０Ｈ（１区３２点）のフォントの最初の８バイトは、
必ず、順に００Ｈ，４０Ｈ，２０Ｈ，１０Ｈ，０８Ｈ，０４Ｈ，０２Ｈ，０１Ｈになっ
ています。そこで、このコードのフォントを読みだして、最初の８バイトがこれに一致
すれば、第一水準の漢字ＲＯＭが存在することになります。

●第二水準漢字ＲＯＭの存在の有無
　漢字ＲＯＭのＪＩＳコード７３７ＥＨ（８３区９４点）のフォントを読みだして、最
初の８バイトの値の合計を２５６で割った余りが１４９（９５Ｈ）ならば、第二水準漢
字ＲＯＭが存在します。

　ソフトウェアでは、必ず漢字ＲＯＭの存在の有無を調べ、漢字ＲＯＭがない機種でも
使えるように、半角文字のメッセージを用意しておきましょう。第二水準漢字ＲＯＭが
ある機種では「國」とか「炬燵」とか「靨」とか難しい漢字を山のように使い、ない機
種では「国」とか「こたつ」とか表示するソフトも考えられますが、今のところ見たこ
とはありません。


<A NAME="BM2_4_3"></A>　　　　２．４．３　　シフトＪＩＳコード

　ＭＳＸでは、漢字ファイルはシフトＪＩＳコード（マイクロソフト漢字コード）を使
います。これは、ＭＳ−ＤＯＳでは漢字ファイルはマイクロソフト漢字コードで扱うこ
とになっているので、それと同じフォーマットを使っているＭＳＸでも、同じコードを
使っているわけです。
　シフトＪＩＳコードでは、漢字開始、終了のコードがなく、半角文字と全角の漢字を
一緒に使えるようになっています。
　ここでは、ＪＩＳコードからシフトＪＩＳコードに変換するアルゴリズムを紹介しま
す。

●ＪＩＳコードからシフトＪＩＳコードへの変換
　ＪＩＳコードの上位バイトをＪＩＨ、下位バイトをＪＩＬとします。シフトＪＩＳコ
ードの上位バイトをＳＪＨ、下位バイトをＳＪＬとします。

　１．ＪＩＨが５ＥＨ以下だったならば、 ＩＮＴ（（ＪＩＨ−１）／２＋７１Ｈ） が
　　　ＳＪＨになります。そうでなかったら、ＩＮＴ（（ＪＩＨ−１）／２＋Ｂ１Ｈ）
　　　がＳＪＨになります。

　２．ＪＩＨが２で割りきれるなら、 （ＪＩＬ＋７ＥＨ） がＳＪＬになります。そう
　　　でないときには、まず、 （ＪＩＬ＋１ＦＨ） をＳＪＬにします。そして、この
　　　ＳＪＬが７ＦＨ以上だったら、さらにＳＪＬに１を足します。７ＦＨより小さか
　　　ったらそのままです。

●シフトＪＩＳからＪＩＳへの変換

　１．ＳＪＨがＡ０Ｈより小さかったら、ＳＪＨから７１Ｈを引いたものをＨとします。
　　　Ａ０Ｈ以上だったら、ＳＪＨからＢ１Ｈを引いたものをＨとします。そして、ど
　　　ちらの場合でも、 Ｈ＊２＋１ をあらためてＨに代入します。

　２．ＳＪＬが７ＦＨより大きかったら、 ＳＪＬ−１ を、そうでなかったらＳＪＬを
　　　Ｌとします。次に、Ｌが９ＥＨより小さかったら、 Ｌ−１ＦＨ をＬとします。
　　　Ｌが９ＥＨ以上だったならば、Ｌ−７ＤＨ をＬにして、Ｈ＋１をＨにします。

　３．Ｈの値がＪＩＳコードの上位バイトに、Ｌの値が下位バイトになります。

</PRE>

<HR>

<P>
※個人的以外の使用および無断転載を禁止します。
<P>
Copyright(C) 1996 by ASCAT All rights reserved.
<P>
<A HREF="../index.htm" >ホームページに戻る</A> <A HREF="tg4index.htm">目次に戻る</A>
</BODY>

</HTML>
