/var/log/hdk.log

2022 年 10 月中旬

prev, this, next


10 (月)

%1 スポーツの日

雨は朝にはあがっていた感じ。

テレビドラマ『孤独のグルメ』Season 8, もう第 10 話だったのか。 (←よくわかっていない) まぁ単体で見られるのでいいか。 いや最新は Season 10 か。 古いのの再放送をしているのか。 ま、いいか。

テレビアニメ『異世界おじさん』も復習がてら第 1 話を。 あらためてみるとアレだな、日本の精霊を呼ぶ? ようなところは日本語でやっていて、本人の魔法絡み (ポケットとか記憶再生とか) はあちゃら語でやっているのかな。 製作の人達は感染症の関係だったので大変なんだろうけど、見る側としては話題になった後で改めて最初から放送してくれるというのはうれしい部分もある。 (話題になった頃には何話も進んでいて途中から見る気はしない、って作品は多数ある。)

連休最終日だなと思ってバイクの給油をかねて夜コストコに行った。 コストコは狙い通りすいていた。 だいぶ湿度が高め。 ややもやっていたし、高架下の信号待ちで上から水が降ってきて濡れて車体が少し濡れてしまったのが、走っても全然乾かなかった。

%2 DOS on DOS

CLOCK が読めなかった謎の鍵は、cooked mode と raw mode にあった。 デフォルトの cooked mode では、途中に仲介が入り 1 バイト単位の入力となってしまいうまく動かない。 Raw mode にすれば直接デバイスドライバーまでおりてくるので動く。 へぇ。

で、でだ。 いろいろ手直しをして、割り込みベクターの待避も一通り入れて、終了のためのデバイスドライバーも入れて、いろいろ動作確認もして、かなりいい感じになったところで、実機から今は仮想マシンに移してある古い Windows 2000 環境を引っ張り出した。 それで試してみると、なんと CLOCK が存在しない? 調べたら DOS 2.x の時は確かに CLOCK だったが、後に CLOCK$ という名前に変更されていたらしい。 そういえばそういう話あったっけ。 あったようななかったような。

それで Windows で CLOCK$ へのアクセスを試みたら、「デバイスの要求が違います」ってエラーが... はぁぁ? そもそも raw をセットする時に EOF がセットされているのも妙なんだよな。 EOF をクリアしたらそのエラーは出ないが読めないし、他にもいろいろ試してみたんだけど解消しないので、CLOCK デバイスの直接使用は諦めた。 代わりに DOS のシステムコールで日時の読み書きをして、CLOCK デバイスのデータ形式との変換を行う。 日付と時刻が別々のシステムコールなので、読み取りは日付を読んで、時刻を読んで、もう一度日付を読んで、最初の日付と一致していなかったら時刻の読み取りをやり直すという実装。 書き込みは時刻を 00:00:00.00 にしてから日付を書き込み、それから時刻を書き込む。 CLOCK デバイスでだけ 1980-01-01 からの日数が登場するため、計算が面倒だが、できた。 2100 年を突破できるように書いたけど、よく考えたら突破する必要ないな?

もうひとつ、Windows の DOS 環境では AH=6 INT 21H の文字出力は通常と経路が違うらしく、水平タブが展開されず記号になってしまう。 CON を raw mode に設定しても同様で、AH=6 は raw mode なのか。 しかし DOS 2.x の IO.SYS を書いている限りは、IO.SYS の CON デバイスドライバーから raw mode かどうかを知る方法はないように思うのだが? って、試したら PC DOS もそういう挙動しているよ。 どういうこっちゃ。 まぁいいや。 この文字出力を使うと、cooked で水平タブを出した時の桁も合わなくなることがわかったので、文字出力はすべて write システムコールにかえた。 (水平タブがズレるのは PC DOS も同じ。) 実は DOSBox だと raw mode に設定した CON からの読み取りがエコーバックされてしまうバグがあるようで、入力は逆に AH=6/AH=7 INT 21H を使うように修正し、ひとまず完成。

ところで、せっかく仮想マシンを引っ張り出したので、Windows の DOS 環境での MS-DOS ビルドも試みた。 予想通り、何も問題なし。 (仮想マシンだからかも知れないが) 速いし。 すばらしい。

2022/10/10 のコメントを読む・書く


11 (火)

%1 かようび

約 3 週間ぶりに午前中出社。 こないだの「坂本冬美特別公演 中村雅俊特別出演」で頂いたおみやげがあったので職場においてきた。 文明堂のカステラとバウムクーヘン。

明治座『坂本冬美特別公演 中村雅俊特別出演』ダイジェスト舞台映像 - YouTube

こんなの出ていた。 見に行った人はこのダイジェストで何となく思い出せていいと思う。 しかしこうして映像で見ると思ったより老けて見えるな... 2 階席からだとちょっと遠いからか若く見えた。

%2 DOS

きのう見つけた水平タブの謎は解けた気がする。

水平タブの展開をするかどうかが、CARPOS というカーソルのカラム位置管理とも連動している。

勘違いの一つめは PC-98 の MS-DOS から始まった。 最初は独自の IO.SYS がまだできていなくて、PC-98 用の MS-DOS の MSDOS.SYS と COMMAND.COM を差し替えて試すところから始まった。 自分が実装していた MSDOS.SYS は水平タブを展開しなかったものの、PC-98 の MS-DOS の IO.SYS は水平タブを展開するから、一見ふつうに表示されたが、CARPOS の設定ができていなかったため、タブを入れてからバックスペースを押すと、その手前のプロンプトまで消されるという事態になった。

で、それを見て IO.SYS の実装を始めたので、深く考えずに IO.SYS 側に水平タブの解釈を実装した。 CARPOS は IO.SYS 側からは触れないので、MSDOS.SYS 側で適当に想像で計算するように作った。

この時に何か既存の DOS の動作を調べることをしたと思うんだけど、DOSBox は行編集モードでタブを表示するくせに消す時は 1 文字単位といういい加減な実装で、他の DOS では DEBUG コマンドの - が消えないから正しい動作... で、INT 29H や ROM BIOS による文字出力等と合わせて行編集を試した時に、行頭に 1 文字出して行編集、で、水平タブを消してもその 1 文字が消えないから、DOS が正しいカーソル位置を把握している、と勘違いしたんだろう。 実際は、水平タブの展開を DOS 側でやっているから、先頭に 1 文字 raw 出力をした上でタブを入力すると、1 桁右にズレた位置に合わせられていることがわかった。 PC-98 版も同様で、普通に使っていたら MSDOS.SYS がスペースに置き換えているから、IO.SYS が水平タブの展開をするかどうかは関係ないわけだ。

で、cooked mode の CON への出力は、ファイル書き込みルーチンの中から OUT というサブルーチンが呼び出され、OUT が公開されていない部分だったため自分で実装したやつで、正しくはそこで CARPOS の更新と水平タブの展開をして RAWOUT に渡す形になりそう。 RAWOUTRAWOUT で標準出力が CON なら INT 29H を使うかデバイスドライバーを呼び出すし、リダイレクトされていたらそちらを使用する。 が、ファイル書き込みの処理から来ているなら CON への書き込みであるのはすでにわかっているので、必ず CON 側の処理になる。 それに対して AH=2 と AH=9 の文字出力にも OUT を使用していると考えられる。 これらは、リダイレクトされていたら水平タブを展開後にファイルに書き込むことになる。 おかしくない? と思ったが、実際に AH=2 で水平タブを出力するプログラムを作ってリダイレクトで試してみると、Windows や既存の MS-DOS でも水平タブがスペースに展開されたファイルが作られるので、間違いなさそうである。

Windows の DEBUG コマンドで raw mode に切り替え後に命令の区切りのタブが記号で見えてしまうというのがあったが、これは Windows の DEBUG コマンドの実装が違うだけなようだ。 Windows 上でも、DOS 2.x の DEBUG コマンドを使えばその現象は起きない。 コードは見なかったが、DOS 2.x のものはおそらく AH=2 か AH=9 による出力を使っていて、Windows のものは AH=40H による出力をしているのではないか? DEBUG コマンドは地味にいろいろとバージョンがある:

他に、確か NEC 版の MS-DOS 6.2 に付属の DEBUG コマンドは、なんと SETVER を入れないと DOS バージョンエラーで動かないバージョンであったw MS-DOS 5.0 付属と同等か?

2022/10/11 のコメントを読む・書く


12 (水)

%1 休暇

WITH ME カートレに参加。 潮来で KT。 もしかして 2 年前の 12 月以来だったか?? 何しろ前回来た時に東関東道の 110km/h 区間があったかどうかの記憶が怪しいんだよなw 早朝 4 時台に出て給油を済ませてコンビニにも寄って高井戸から首都高、東関東道の PA まで突っ走り休憩、それでのんびりいったつもりが 7 時過ぎ (ゲートオープン 7:30) という... 今回何とか潮来のインターチェンジからの道順を覚えられた。

午前中の走行でベストタイムは 37.9 秒ほど、午後は乗りやすいマシンから絞り出して偶然 37.3 秒あたりが出た。 午前は時々間隔を開けるための休憩ラップを挟みつつで体のつらさはそうでもなかったが、午後の後半は休憩ラップでも首がきつかった。 やっぱりスポーツカートと比べても明らかにきついなぁ、レーシングカートは。 コースの特性もあるとは思うけど。

たまたま、先日のレンタルカート耐久レースにも来ていた、いつも上位にいらっしゃる速いチームの方が、今日潮来で午前中だけ別の (WITH ME でない) グループで走行をされていることがわかって、少し話をして、観察もさせてもらった。 なんで午前中だけか? 午後に潮来の近くでお仕事があって、遠くてあまり来ることないしちょうどいい機会だからと午前中にカート走行を入れたんだそうで... つまり午後からお仕事... パワフル!! 3 人 3 台並んでハイペースで走行を重ねているのを見るのはなかなかおもしろい。 たまに雨がぱらつくこともあったため時々滑っていたものの、基本的には非常にスムーズに走行していた。 最終シケインに向かう短いストレートはアウト側まで出ていたが、最終コーナーは真ん中ぐらいで立ち上がる感じだったな。

帰りの車の中で信号待ちの間に後ろの荷物に手を伸ばしたら、体がピキッとなって焦ったw 神経痛は何とかごまかしているが、やはり潮来でレーシングカートに乗ると体がきついなw まだ筋肉痛になっていない筋肉痛っぽさはあるんだけど、よほど意識して姿勢を保っていないと神経痛が顔を出しそうな感じになっている。

首都高の渋滞を避けようとして都心環状線逆回りに入り、そこから中央道方面に向かったものの外苑で渋滞最後尾に追いついたので、外苑で降りた。 高井戸まで 40 分はちょっとひどい渋滞のように思ったので。 下もまぁ渋滞はしていたんだが、道も間違えたし... 外苑降りてから右に出て左折帯、までは悪くない選択のようだったが、その突き当たりを右に出て国道 20 号のトンネルに向かったから新宿駅近くの渋滞があった。 地図を見ると、あの突き当たりを左折してちょろっといって首都高くぐって右折、とやると千駄ヶ谷方面に出られたんじゃなかろうか。 そうすると初台までもう少しスムーズに出られたかも知れない。 とはいえ上が渋滞していたら下も渋滞するのはよくあることで、どれが速かったかは...

%2 鈴鹿の話

なんと参加者に今年の F1 日本 GP を現地観戦に行った人がいらっしゃったのでチラッと話をしてみたところ、レース再開タイミング、現地組的には適切な感じだったらしい。 というのは、15 分後のレース再開のアナウンスがあった時点で雨は降り続いており、えっ、再開するんだ、もしかして雨が上がるというデータがあるのかな、と、そんな感じだったみたいだ。 んで実際に再開の時には雨が上がった、と。 確かに、実況でも雨が上がりましたねと言ってはいたが、さすがにその雨の降り方の肌感覚までは想像できなかったな。

%3 MS-DOS の話

自分が実装したやつは Ctrl-C のチェックがおかしくて、出力をなおしたら出力の Ctrl-C チェックがなくなってしまっている。 それに、入力についても Ctrl-C が入力になってしまうケースがある。 Non-destructive read をして、入力ありになったとしても、それが Ctrl-C の場合があるから、もう一度 Ctrl-C かどうかのチェックをしないといけないみたいだ。

で、出力のほうは、stat は 4 文字ごとにチェックする、みたいなコメントが書かれた謎の変数があって、その変数はどこからも参照されていない。 もしかすると 1 文字ごとのチェックではないのかも知れない。 そこのところ、実は古い 2.00 の MSDOS.SYS のバイナリが MS-DOS のソースコードと一緒に含まれているので、それで挙動を確認できそうな気がする。 すでに自作デバイスドライバーを入れて一応は動く IO.SYS を手にしているわけで、DOS 上で動く IO.SYS まで作ってしまったし、それに手を加えて実際の MSDOS.SYS で non-destructive read がどのタイミングで行われるのかを調べてみると良さそう。

というわけで調べてみると、確かに出力 4 文字ごとにチェックしているみたいだ。 へぇ。 AH=2 の出力でも 4 文字ごとになるから、どこかにカウントを保持しているのか? そんな変数あったっけ?? それともあの 1 バイト変数のどこか違うビットを書き換えて利用しているのか?

2022/10/12 のコメントを読む・書く


13 (木)

%1 きのうの給油

157 円/l。 燃費計算 16.7km/l。 燃費表示 16.7km/l。

%2 もくようび

曇り時々雨。

筋肉痛!!! 首まわりががっつり筋肉痛! やっぱりレーシングカートは違うね! 今回 10 分かける 6 回だから、走行時間だけなら、5 時間を 4 人で走りきるスポーツカート耐久レースのほうが長い。 1 周の長さが 1.5 倍ぐらい違うけど、それよりもパワーとタイヤの違いだろうな。

DAZN の Wednesday F1 Time の F1 日本 GP 振り返りは長めの 57 分。 3 時間レースはなんとモナコもそうだったらしい。 で、モナコのチェッカーフラッグは間違えて時間切れの 1 周後に出てしまっていたらしい。 へぇー! モナコは周回数が 75% を超えていたのでポイント数の混乱はなかったし、周回数のミスは誰も気にしていなかったんだな。

W シリーズは予算の問題があって残り 2 レースが開催できない状況らしい。 そうするとシンガポールで今季初クラッシュしたチャドウィックがそのまま 3 度目チャンピオンか。 ほぇー。

テレビドラマ『祈りのカルテ』第 1 話。 研修医の話、主人公の最初は精神科、みたいな、そんな感じ。

%3 MS-DOS

出力の Ctrl-C チェック、これ cooked mode の CON への出力でもきくので、OUT ルーチンでやるべきなんだな。 なんか参考になりはしないかと v1.25 のほうのコードを見たら、OUT の実装があった。 BIOS とガッツリ密接にくっつくスタイルだったようでそこは v2.0 とは大きく違っているが、水平タブの展開や CARPOS の更新もあるし、その処理を見てみると US-ASCII の制御文字 (0〜31 と 127) は全部特別扱いの範囲でどれも 1 文字進みはしないようだ。 実際試したらそうだった。 言われてみればベルだってカーソルは進まないよな。 PC DOS では IBM の固有の記号類が出るコードもあるけど (顔の絵とか矢印とか、JX だと罫線とか)、実際それも 1 文字にカウントされていないみたい。 へぇー!

ってわけで OUT の実装の見直し... そうだ、印刷機能もあるんだ。 Ctrl-P でプリンターに同時出力するやつ、あれも OUT でやるようだ。 忘れていた。 Ctrl-C については v1.25 は毎回チェックのようだった。 v2.0 は CHARCO 変数を参照して何とかする... わざわざ 2 進数で初期化されているため、何かビット単位で使うフィールドになっていると推測。 それで、適当に上位 4 ビットと下位 4 ビットにわけ、上位 4 ビットを 1 引いて、マイナスになったら下位 4 ビットを上位 4 ビットに移して Ctrl-C チェックをする、っていう処理を実装した。 4 回ごと固定なら 00010001b をローテートしたり、256/4 を足したり引いたりしてキャリーフラグを見て処理する手もあるんだけど、回数を 5 回とか 7 回とか任意に変える意図があったのかな? それでも回数を表すなら自分なら 2 進数では書かないと思うが... ま、他のコードから参照されていないんだから、どう実装しようが影響はないはずである。

プリンター同時出力と Ctrl-C チェックの関係は、バイナリの MSDOS.SYS の挙動を調べたところでは特に変わらず、別のプリンター出力のシステムコールを使用した場合は毎回チェックになっていた。 ので、そうなるように実装した。 AUX を含む共通ルーチンで毎回 Ctrl-C チェックをするように作ったが、Ctrl-P のプリンター同時出力の処理は Ctrl-C チェックをしないよう、その共通ルーチンを使わない形で実装した。

さてビルドした PC 用 DOS は自分の JX エミュレーターで日本語モードでも英文モードでも起動するようになっているので (例の seek コマンド無視を活用すれば英文モードでも 720KiB フォーマットで起動可能)、ふと思いついて、v1.25 のほうにバイナリで入っている BASICA.COM を実行してみたら英文モード (PCjr 互換) では BASIC が起動したよ! DOS のファイルは扱えるけど CHDIR が使えない BASIC だ! PCjr は最初から DOS 2.x だけど、ROM BASIC は PC とも互換性があったのかな。 日本語モードでは仕様が違うらしく BASIC は起動しなかった。

2022/10/13 のコメントを読む・書く


14 (金)

%1 きんようび

晴れ時々曇りみたいな天気だったのかと思っていたが、夜買い物に出かけたら道路は濡れていた。

テレビでやってた映画『るろうに剣心 最終章 The Final』。 2021 年の邦画。 映画館で見た映画。

%2 DOS

PC ではカーソルキーやファンクションキーが BASIC で言うところの CHR$(0,72) 的な感じで NUL とキーコードそのものというふうに展開されるしくみがあり、MS-DOS のソースコードでは IBM とか IBMVER とかみたいな定義が真にされているとそっちのスタイル、自分でビルドしたやつは MSVER にしたからこれは NEC 版 MS-DOS と同様に VT52? 互換のエスケープシーケンスになっていて、そのため IO.SYS にキーコード変換を実装した。 ところがアプリケーションがその IBM 方式を期待しているところがあり、切り替えられると便利だな? ってことで切り替え機能を実装した。 ついでに少し入力ルーチンを整理して。

で、確認したら動かない。 F3 全然きかない。 おかしいな? と思ったらきのうの修正でちょっとやらかしていたことがわかったw まずそれを修正して、それからその切り替え機能を追加だ。 うまくいった。

うさんくさい DOS on DOS も割といろんな環境でよく動いてくれる。 ただ 8088 エミュレーションだと文字表示がむちゃくちゃ遅い。 それもそうか。 せっかくの INT 29H も、割り込みベクターを入れ替えてシステムコールなんだからな。 というわけで、標準出力が special の時だけは割り込みベクターの入れ替え無しに直接元の INT 29H を呼び出すハックを作った。 INT 29H ってのはシステムが使う fast path なので、さらにシステムコールを使うことはできない。 となればシステムが別物に化けていても問題ないだろう、ということで。 知らんけど。

2022/10/14 のコメントを読む・書く


15 (土)

%1 どようび

朝は曇り、午後は晴れた。

前々から考えていたネタ、大型特殊の運転免許取得に挑戦してみることにしたw 30 代最後だしな!w 調布の自動車学校で大型特殊教習があることがわかったので、これなら行きやすいと思いさっそく申し込み。 なんと身分証明書が運転免許証の他にもうひとついるって、へぇ? それから、大型特殊教習は都度予約でなく、最初に空いている日程を伝えて、自動車学校側で全部割り振るんだそうで。 へぇ。 まぁ、 6 時間 しかないから、本当にそれで大丈夫なの? と思うくらいあっという間になりそうである。 ちょっとこんでいて 1 か月ぐらい先になりますよー、と言われていたが、いざ埋まったのを見ると再来週に一気にやる作戦じゃないかw 例によって適性検査もあり、今日が空いていたのでそれにして、受けたらその場で数分のうちに検査結果が出てきた。 へぇぇ。

なお調布自動車学校、以前は国道沿いにあったのが移転したんだそうだ。 元ボウリング場と言われて、あああ、ってなった。 これじゃん。 前にこの国体の時にボウリング場に来ていて、今見ると何かこのへん変わったっぽいよなと思ってはいたが、まさかボウリング場が自動車学校に化けていたとは。

そうそう、例によって視力検査の装置は左右の像がズレてしまって重ねられなくて、裸眼ではパスできなかった。 めがねをかけてもズレていたが、矯正により片目でも両目視力をクリアできてしまう。 二輪免許の時は教習中のみ眼鏡等で、免許併記の際は試験場次第という話がすんなり通ったけど、なぜか今回は時間が掛かった。 けどまぁ結局そうなった。 ま、40 歳も目の前まで来ているんだから、そろそろ試験場でも裸眼でパスできなくなっていても不思議はないんだがw

調布自動車学校は普通二種の教習もやっているそうだが、AT 限定の料金が書かれていて、MT はお問い合わせくださいとなっている。 まぁ、教習車は普通一種用があるから、できないことはないけどね、ってところなんだろうな。 普通二種も一括予約って書いてあったのでチラッと聞いてみたら、主に企業様 (おそらくタクシー会社) 向けで、一般の人であっても、1 週間で一気にみたいなやり方をするんだそうだ。 へぇぇぇ。

大型特殊の 6 時間教習も短いなと思うが、限定解除シリーズだと、車の AT 限定解除で 4 時間、バイクの小型限定解除にいたってはなんと 3 時間らしい... うひゃー。 普通二輪の AT 限定と小型限定 (小型は MT OK) の組み合わせの限定解除も 3 時間らしいが、そんな人いるんか?w

%2 MS-DOS と PCjr

自前ビルドの MS-DOS を PCjr に対応させようとしてごちゃごちゃやっていた。 きっと大丈夫だろうとは思うんだが、実機が手元にないので本当に動くのかはわからないw PCjr 対応としては基本的にはディスクフォーマットの話で、JX の FORMAT コマンドに /8 /4 /1 というスイッチがあって、それらの組み合わせ 8 パターンは media ID の F8H〜FFH に対応していることを今更ながら知った。 うち /4 は PCjr 互換の (倍トラックでない) フォーマットのオプションだ。

じゃあ PCjr の PC DOS の FORMAT コマンドには /4 以外は指定できるはず、っていうことで調べると確かにできたのだけど、/8 をつけた時かな、ブートセクターのパラメーターブロックがなんと空っぽ (00) になってしまうことを知った。 FAT の先頭の media ID をあてにするしかない。 へぇぇ。

でまぁ、そのへんを作ったなら JX でも PCjr ディスクのアクセスができるようにしたいよね、と思って適当に対応した。 DL=40H で起動してきていれば JX, media ID を見れば倍トラックは FCH 未満だから、FCH 以上だったら 40H のビットをクリアする。 欲を出してブートもできるようにしようと思って、ブートセクター内と IO.SYS 内のファイル読み込みルーチンでも 40H の一時クリアを実装した。 うまくいっていれば、360KiB フォーマットにはなるが同じディスクから英文モードでも日本語モードでも起動できるようになっているはず...

なお JX の英文モード BIOS はやはり DL=40H での INT 13H ディスクアクセスはエラーになってしまうようだ。 AH=0 だと通るが AH=2 は通らない。 ハードウェアが違うので seek コマンドの部分だけは書き換えてあるはずだが、PCjr との互換性重視で、機能拡張をしようとは考えなかったのかも知れない。

2022/10/15 のコメントを読む・書く


16 (日)

%1 にちようび

晴れ。 のんびり。

古いフロッピーディスクドライブを発掘した。 ケーブルが同時に出てくることを期待したが、出てこなかった。 ウーン。 捨てちゃったかな。 2009 年に手放したマザーボード GA-7DXC と一緒に使っていたドライブだしな。 Sun Microsystems Ultra 20 Workstation のマザーボードに FDD のヘッダーがあり、ケーブルさえあればつなげられる、と思ったが、電源も見当たらないのでその変換ケーブルも必要か。 フロッピーディスクはいくつか古いデバイス付属のディスクが出てきたが、シャッターを開いてみるとディスクの状態が怪しい。 シャッターがあるので 5.25 インチほどひどくはならないものの、さすがに 20 年の時はなかなかに厳しい。 ダイソーで買った 2 枚 2 色のフロッピーディスクも出てきて、こっちは見た目はきれいだった。

この前見つけ損ねた、『孤独のグルメ』Season 10 の第 1 話と第 2 話を見つけたので見た。 よしの食堂 (大衆食堂)、CABE (インドネシア料理)。

%2 MS-DOS

たまたま自分が実装したルーチンの挙動が間違っていることを発見した。 PC DOS のコマンドラインで Esc キーを押すと、入力内容を取り消して (今入力中のものを捨てて) やり直す、というのがあり、画面には \ が出て改行されるのだが、この時に本来であれば改行後最初の桁位置まで (プロンプトの桁数分の) スペースが入れられる、という挙動なはずのところ、8 桁スペースが出る状態となっていた。 TAB って名前のくせに、指定個数のスペースを出すってルーチンを書かなきゃいけなかったらしい。 なおしたらいい感じになった。

で、その桁数管理が CARPOS なのだ。 水平タブの桁位置にも使うけど、水平タブだけなら下位 3 ビットさえあれば事足りる。 プロンプトは 8 桁を超えることもあるから、CARPOS が大事なのだ。 (なお 256 桁表示すると 0 に戻ってくる。)

それから、IO.SYS を relocatable にした! 最初、デバイスドライバー部分のセグメントさえ書き直せばいいのではと考え、どうせならと思ってデバイスドライバーのテーブルを実行時に生成するコードを書いたが、それを書いてから、RE_INIT の存在を思い出した。 これは、MSDOS.SYS の準備ができて、システムコールが使えるようになった状態で、CONFIG.SYS の処理に移る前に呼び出される IO.SYS のルーチンで、想像では、PC-98 の KEY.TBL とか、JX の $USR16.FNT とかの読み込みはそのへんで行われるのではないかと思っている。 あっ、IBMIBMJAPVER が真になっていると使われないので、JX 版はそのへん書き換えてあるんだろうけどね。 まぁそれで、それが FAR CALL なので、やっぱり relocatable にしておかないとだめなのだ。

というわけで EXE ファイルにして、ヘッダーの relocation table を見てアドレスを補正するプログラムを書いた。 JX なら 200H, 他なら 80H のセグメントアドレスに IO.SYS のデバイスドライバー部分が来るようにする。 デバイスドライバー部分が予定と違うアドレスにあったら転送するというのは前に実装してあったから、そこはそのままで OK。 いろいろ動作確認して、良い感じだった。

あとは実機も試したいなと、フロッピーディスクドライブは今は使えないが、El Torito ブータブル CD なら簡単に試せる。 CD-RW に書き込み、ThinkPad X201 に USB 光学ドライブをつないで試すと、何事もなく動いた。 あまりに何事もなくておもしろみがないw ディレクトリの中の DIR が 1 行ずつ seek していて遅かったが、これは BUFFERS を指定したら解決した。 なるほど。 まぁそもそも光学メディアなのでフロッピーディスクドライブに比べたらずいぶんと速い。 あとこの ThinkPad には以前インストールした FreeDOS が残っていたので、そこでのビルドと DOS on DOS による起動も試した。 これも何事もなくておもしろみがないw

なお ThinkPad で BASIC.COM は DOS 2.x 上でも動かなかった。 元 IBM とはいえさすがに ROM BASIC は残っていないらしいw

%3 PC DOS

PC の ROM BIOS のデータ領域がセグメント 40H にあるというのは有名な話だが、じゃあその長さは? というとよくわからなくて、メモリーダンプを見ると 50H にはもうファイルシステムの一部みたいなのが見えていて、使われているようにも見える。 が、IBMBIO.COM は通常は 70H にあるようだ。 50H はルートディレクトリエントリの一部が壊れて見えていて、どうも起動時に何か使ったあとのよう。

んで調べると 50H には用途があるらしく、特に BASIC が使う部分があるようだ。 確かに PCjr BASIC を起動すると一部にいろいろ書き込まれる。 あと INT 1EH のベクターもここに設定されるんだと。 確かに PC DOS 上だと 0H:522H に設定されている。 JX の日本語 DOS でも 0H:522H は同じみたいだが、日本語 BASIC が使う場所は違うようだ。 へぇ。

自分の実装は 80H からにしたが、60H からの 512 バイトはディスク BIOS の DMA 制約の回避用のバッファーにしている。 DMA 判定を入れてあって、メモリーが 64KiB 以下か、DMA の制約がなさそうな環境であれば使わない仕掛け。 JX は DMA 無しなので 1E0H からを使うことはないが、そこは BIOS が使用する。 PCjr も DMA 無しなので 60H からは誰も使わない。 その 512 バイトを詰めてもいいんだが、面倒なのでやらないことにしたw エミュレーターも、デバイスレベルでなく BIOS レベルでのエミュレーションであれば、制約がないものがあるかも知れない。 DOSBox なんかがそうかなと思って試してみたら、違って、なんと PCjr モードにしても DMA 制約があるようだw

PC DOS はというと、DEBUG コマンドでわざと DMA 境界あたりにディスクのセクターを読み込ませてから、メモリーの検索をしてみると、IBMBIO.COM の後ろ? なのかな? 何か中途半端な位置に読み込んだデータが現れる。 PCjr エミュレーションだと違うっぽいな。 同じアドレスを何かの作業用バッファーに使っているようではあるが、境界をまたいでアクセスしても変化しない。

2022/10/16 のコメントを読む・書く


17 (月)

%1 げつようび

曇り時々雨。

テレビアニメ『うる星やつら』。 1 話。 GYAO! で配信。 初代アニメ作品は生まれる前から幼稚園入園前ぐらいの放送であり、再放送でも見たことがなく、今作が初めてになる。 絵は今風だが高橋留美子っぽさが出ている。 いきなりのどたばた鬼ごっこで主人公と彼女と宇宙人の三角関係がはじまった。

%2 DOS

きのう何の問題もないなんて書いておきながら、今日になったらバグが見つかっているんだからいい加減なものだw 遅い 8088 向けにいろいろと改良を施していたら、性能改善効果はほとんどないのに、別のところで挙動が変で、バグを入れていたことが発覚した。 DMA 判定をぶっ壊していた。 やり直してみると DOSBox はやはり PCjr 指定でなくても DMA 境界は存在しなかった。 そうだよねそうだよね... DOSBox は確か BIOS レベルで途中すっ飛ばしているはずだからな。 Bochs や QEMU みたいな ROM BIOS すらなく、特別な方法でエミュレーターを呼び出すだけになっているはずなので。

んで不思議なのは文字表示が遅い。 IBM の日本語 DOS と比べて明らかに遅い。 CON まわりを速くしてはみたが、そもそも CON は出力時は INT 29H という fast path が使われるのでここまで来ない。 Ctrl-C の入力チェックのほうは使われるから一応は効果あるだろうと思ったが、計測できるほどの差はなかった。 MSDOS.SYS だけバイナリの 2.00 と差し替えても遅いから、自分の IO.SYS 実装の問題なのかなぁ。 まぁ、2.00 のバイナリのほうが若干速いので自分の IO.ASM の実装のまずさもあるのだろう。 IO.SYS は、INT 29H が INT 10H を使う時に BX 指定なしになっているのかな、と思ったけど試しても大差はない。 わからん...

さて、DOS ってやつは Ctrl-C がうまく反応してくれないことがあったような気がする。 Ctrl+Break とか STOP キーとかのほうがきく、ってのは BASIC のほうだったかなー、そのへんはもう記憶があやふやである。 しかし Ctrl-C がうまく反応しない場合がある理屈は今は理解できる。 文字表示の際に Ctrl-C のチェックは行われるが、これは CON の入力バッファーの先頭 1 バイトを非破壊読み込み (non-destructive read) することで行われている。 つまり... うっかり他のキーを押してしまうと、入力バッファーの先頭にその文字が入ってしまうので、それが入力されるまでは Ctrl-C は処理されなくなる、という残念仕様なのである。

とにかく DOS はシンプルで、速い、みたいな感覚が (後の Windows 95 などが遅かったために) あるが、この構造を見ても速くはないことがわかる。 自作仮想マシン版でわかったように、MS-DOS はデバイスからの割り込みがまったくない環境でも動かせる。 そのためにキー入力待ちも Ctrl-C チェックも何もかもがポーリングで、ディスクアクセスだって (たいていの機種では DMA が使われていたが) ポーリングでやっても問題ないのである。 逆に言えば文字出力中も Ctrl-C チェックに CPU を使うし、ディスクアクセス中に他の仕事ができない仕様なのだ。 バックグラウンドで処理をするのは、せいぜいメーカーが各機種に合わせて作ったプリントスプーラーがあった程度だ。

2022/10/17 のコメントを読む・書く


18 (火)

%1 かようび

夜ちょっと雨が降ったっぽい。 さむい。

第 8 波来始めたか? そりゃー来るよね、だって学級閉鎖やら何やらで盛り上がっていたのが 7 月あたりでしょ、もう 3 か月経ったから、自然感染の人の免疫には期待できなくなってきた頃だ。 12 月に入ったぐらいに落ち着いてくれるといいけど、そうならないと厳しい冬になりそうだな。

%2 MS-DOS

我ながら笑えるぐらい日々バグを作り込んでいる。 仕事じゃないし何か大事なデータを失うわけでもないのでいろいろと雑だw 今日は AUX を試したら動かなくなっていて、おかしいなと見直したらきのう CON を速くした時にぶっ壊していたことがわかった。 ついでだから AUX も速いほうのエントリーポイントに差し替えた。 ついでだから PRN も見たらこれは最初から動かなかったw これ実は参考にした SKELIO.ASM がすでに間違っているのである。 PRN_WRT は CALL されるサブルーチンではないので RET 命令で終わってはだめである。 で、DOS on DOS 用の実装と独自仮想マシンの実装は共通ルーチンにしたので動くようになっているが、PC 用は ROM BIOS を使うあたりが SKELIO.ASM と似ていたのでそのままになっていた。

それと出力ルーチンの最適化を施した。 もっともよく使われるであろう AH=2 のシステムコールができるだけ分岐無しで出力ルーチンにたどり着けるよう配置を変えた。 他に AUX や PRN のシステムコールも CALL RET より JMP のほうがバイト数が減るからいいかなと。 いろいろやってから日本語 DOS との文字表示比較をしたら変わらないぐらいになっているなぁ! 細かく調べていないけど、どれかの修正がきいたらしい。

まぁサイズを無視するなら AH=2 は OUT とは別に同じような出力ルーチンをもうけたほうが都合が良いと思われる。 システムコールは dispatcher がいろいろレジスターの保存をしてくれているみたいなので、結構壊してもいいレジスターが多いんだが、OUT は壊さないようにしているからだ。 それでも PUSH POP が 2, 3 ペアいらない程度なんだけど。 Ctrl-P の印刷処理まであるのでふたつ実装を入れるとだいぶ大きくなるのはなる。

子供の頃に某デバイスドライバーのリバースエンジニアリングか何かで覚えたテクニックは、割り込みフックの戻り番地を ljmpw 命令の機械語の後ろに直接書き込むというやつだ。 これは便利なのでよく使っていた。 その後中学生ぐらいになってから、マシン語ゲームグラフィックスという本に載っていたプログラムが思い切り機械語動的書き換えをしているのに度肝を抜かれたが、結局それにインスパイアされる形で今回の IO.SYS 実装でもいろいろ怪しげなコードを使っている。 まぁ派手に命令を書き換えるのではなくて、アキュームレーターに対して immediate と比較する TEST 命令の機械語に置き換えて処理をスキップさせるとか、単に 1 バイト・2 バイト先への JMP 命令 (2 バイト) を書くのはもったいないから TEST 命令の機械語 (1 バイト) をおいておくとかそういう。 TEST ってのは便利で、レジスターは壊さないし、キャリーフラグは確実にクリアされるし... でもこう機械語の長さが手に取るように想像できてしまうのは昔エミュレーターを作ったからなんだよなw ここはアキュームレーターを使ったほうが短い、ここはどっちでも変わらない、ここは MOV の代わりに XCHG を使ったほうが短い、ここはレジスターを用いたアドレッシングにしたほうが短い、的な...

2022/10/18 のコメントを読む・書く


19 (水)

%1 すいようび

晴れ。

今朝はさすがに寒くて頻尿に... 4 時、6 時、8 時、10 時、11 時ぐらいな勢いでトイレに行っていた。 「洗えるどこでもカーペット」を引っ張り出していすに敷いてその上で仕事。 ベッドには N ウォーム敷きパッドを 4 か月ぶりに復活させたので今夜は大丈夫だろう...

%2 MS-DOS

次は PC-98 版 IO.SYS を実装してみようかな。 とはいっても市販バージョンみたいな INT DCH などは実装せず、最低限の CON AUX PRN CLOCK とフロッピーディスクのアクセスに対応するだけのをね。 フロッピーディスクは HD/DD 対応が必須だろうからちょっとよく知らないので調べないといけない。 まぁテキスト VRAM も、昔は直接アクセスするプログラムを書いていたもんだが、もう忘却の彼方なので調べ直しだな。 IBM PC の CGA/EGA なんかは構造がシンプル過ぎてほとんど覚えてしまっているけど (それでも白黒のほうは覚えていないが)、JX (日本語モード) やら PC-98 やらは 2 バイト文字をどうするかで属性フィールドか何かがごちゃごちゃしていて、文字コードが Shift_JIS (JX) とか JIS X 0208 (PC-98) とかだったのは覚えているけど、細かいところはもう忘れてしまった。

DMA 制約が PC-98 で偶数バイト単位ってなかったっけ? と思ってテクニカルデータブックを探して見てみたがそんなことは書いていなさそうだった。 64KiB 境界があるのは IBM PC と同じなので、IBM PC でやったのと同じような実装が使えるはずだ。

%3 バス

先日からニュースでバス横転事故が報道されており、その現場の小山町ってのは富士スピードウェイや、何度も参加しているカートレースが開催されるサーキットがある町でもあり、気になってしまうが、場所は富士山五合目からおりる道なんだそうでそっち側は自分は走ったことはない。 バスに関しては基礎知識としてドラムブレーキ、エアブレーキ、排気ブレーキ、リターダー、ホイールパーク、フィンガーシフトなどいろいろあってその辺の知識が自分ら素人以上にまったく足りていない突っ込みどころ満載な意見も見られる。 自分が借りたことがある 2t アルミバンなんか、中型 8t 限定免許で運転できるけど、当然のように 2 速発進で、排気ブレーキもついていた。

ベーパーロック現象、ブレーキを動かすブレーキフルードの温度があがり気泡が入るというその現象は、エアブレーキでは空気で動かしているのでおこりえない。 まぁエアブレーキとフルードを組み合わせている車種があるみたいなのはそうなんだけど、それもフルードはペダルの近くにあるはずなんだ (路線バスで見たことがある気がする)。 乗用車やバイクのようにフルードで直接ブレーキを駆動するのでなく、その先にエアがある以上は、ブレーキを使いすぎてフルードに気泡が入るほど温度があがるというのは考えにくいのではないかと思っている。

エアがあるのはバスに乗車しているだけで音で伝わってくる。 運転手がブレーキペダルを踏み込むと圧縮空気がタンクから送り込まれ、離すと送り込まれた空気が外部に放出されるから、離す時に空気の音が外に聞こえる。 ホイールパーク (駐車ブレーキ) は逆で、かけると空気が放出され、解除すると空気が送り込まれる。 空気圧が不足すると自動的にかかる仕掛け。 圧縮空気は圧縮機で作られていて、一定圧より下がるとゴゴゴゴと音をたてて圧縮を始め (タイヤの空気入れみたいなものの大がかりなバージョン)、一定圧に達するとプシューッみたいな音がして作動が止まる。 電車と同じような感じだけど、バスの圧縮機は電動モーターでなくエンジンの回転を使って動いていると思う。

タイヤ痕というのもブレーキによるものだけでなく、ステアリングを前輪のグリップ以上に動かして曲がりきれずに残るケースだってあるのだ (今回のは知らないけど)。 今日のところはブレーキ過熱の痕跡の報道も出てきているが、それにしたってトラブルでブレーキを引きずって過熱ということもあるので、それだけで運転手のせいとはとても言えない。 スキーバスの事故の時を思えば、あんな険しい道でブレーキを失って死者 1 名は極めて最小限の被害におさえられていると言えそうで、今後の調査を待つだけ。

2022/10/19 のコメントを読む・書く


prev, this, next

/var/log/hdk.log コメント一覧

トップ / 日記索引 / 日記 (2022 年 10 月中旬)

Hideki EIRAKU