第二章 『 SWI2――OS-9への入口』
6809が動くようになった。簡単なものだ。
小さなテストプログラムを走らせ、レジスタを見る。SWIで止める。逆アセンブラも付いた。1文字入力と1文字出力を付けると、昔のシングルボードコンピューターにモニタープログラムを載せて遊んでいた頃のようで、なかなか面白い。
ASSIST09モニターでも入れてみるかと思ったりしたが、FM-7やFM-11で使っていたプログラムもある。
ただ、これはハードルが高い。FM-BIOSの出力先を作らないと行けないのだ。
OS9のプログラム。これはハード依存が少ないはずだ。だったら、これを動かせないだろうか。
もちろん、そのままでは動かない。6809の命令が動くだけでは、OS-9のプログラムは動かないのである。システムコールがSWI2が動けば形ばかりでも動くと思った。
6809にはSWI、SWI2、SWI3というソフトウェア割り込み命令がある。
SWIはデバッグに使っていた。好きな場所に入れておけば、そこで止められる。これは便利だ。さっきの6809エミュレーターでも動作は模倣している。
ここで止めて、スタックに入ったレジスターを表示できるのだ。
ブレークポイントは、プログラムの元々そこにあった、データを待避しておき、SWIを埋め込み、再開は元のデータに戻しここから再開させればよいのだ。
OS-9ではSWI2がシステムコールである。OS9用のプログラムの中には、
SWI2
FCB $xx
....
という形で命令が入っている。
SWI2の次の1バイトが、OSへ何を頼むのかを示している。
ファイルを開け。
文字を出せ。
メモリを確保しろ。
プロセスを作れ。
モジュールを探せ。
プログラムを終了しろ。
そういう要求である。
つまり、SWI2がきたら、その次のサービス番号を見て、OS9のマニュアル通りの必要な処理をしてやれば、OS-9のまねっこが出来るのである。
6809のエミュレータを書いたついでに出来そうな感じがする。
ここで少し、自分の会社での仕事の話をしておきたい。
私は、昔から「人に使わせるためのツール」を作るのが専門だった。
「オホーツクに消ゆ」という有名なソフトがあるが、そこで使われている絵を描いたソフトや表示プログラムは学生時代の私が作ったものである。
その後、ゲーム会社にいた頃も、一つのアドベンチャーゲームを最初から最後まで全部書く、というより、アドベンチャーゲームを作るための基本システムを作る。あるいはロールプレイングゲームを作るための基本システムを作る。そういう仕事をすることが多かった。まあ、シナリオは書けないし、ゲームを考えるより、何か仕組みを作る方が楽しかったのだ。
ゲームは分業できる。ドラクエ型のロールプレイゲームの場合、シナリオを考える人。マップを作る人。絵をデザインする人、音楽を作る人。そしてそのデータを入れる人、テストする人がいる。
その人たちが使えるように、ツールを作る。自分だけが使えればいいプログラムではない。「ほかの人が使える道具を作る」のが私の仕事だった。
その後、仕事がカーナビへ変わっても、やっていることは案外同じだった。カーナビの検索システム用データを作るためのツールを作る。大量の地図情報や検索情報を、システムで使える形に変換する道具を作る。
だから考えてみれば、このソフトでやろうとしていることも、それほど違わない。
それはそれで楽しいのだが、6809を一個動かしたいだけではない。OS-9のコマンドを一つ起動して喜びたいだけでもない。Windows上でプログラムを書き、コンパイルし、ファイルを操作し、ほかのエミュレーターで動くソフトを作ってみたいのだ。
つまり、また「ツール」を作ろうとしているのである。
自分でも、「ああ、結局こういうものを作るのが好きなんだな」と思った。
OSそのものにも、昔から興味があった。
FM-7では、簡易なDOSを自分で作ったことがある。
もちろんOS-9のような本格的なものではない。FM7用のグラフィックエディター用のファイルシステム、入力システムである。
FM77AV用では、プログラムを呼び出す仕組みを作り、ツールの切り替えに使った。こういうものを作るのは、とても面白かった。
しかし仕事となると、OSそのものを書く機会はなかなかない。ゲームの基本システム、開発ツール、データ作成ツール。そういう「OSの一段上」のものを作ることは多かったが、本格的なOSを一から作るという仕事はなかった。
だから、SWI2を見ていて、ふと思った。「これ、システムコールを一個ずつ作っていけば、OSみたいになるじゃないか」いや、正確にはOS-9互換環境である。私にとっては、長年やってみたかったことである。こうなると止まらない。
まず、OS-9の小さなプログラムを動かしてみる。FM7やFM11のエミュレーターがあるので、様子が分かっている。
そこで作った単純なプログラムを取り出して実行する。2026年現在、ネットを探すと便利なソフトが一杯フリーで出ている。D88/D77化したイメージから取り出した小さなファイルを、6809のメモリーに見立てた64KBの配列に読み込み、指定のアドレスから6809トレーサーが1インストラクション毎に読み出し、進んでいく。画面が実行位置とレジスター表示の列で埋まる。
そして、SWI2に来て止まる。この6809エミュレ-ターのSWI2用関数で、サービス番号をチェックする。
F$系か、I$系か、そしてそれぞれの番号がある。
OS9の、F$系はプロセスやメモリ、モジュールなど、システムそのもののサービス。I$系はファイルや端末など、入出力関係。
たとえばWriteが来たなら、指定されたパスへ文字を書けばいい。
最初は単純にコンソールに見立てた、Windowsのウインドへその文字を出す。
例えば Cでprintf("ABCD\n");と書いただけのプログラムで良い。
この6809のトレーサーに渡し、読ます。
文字用に作ったウインドウに文字が出る。
「ABCD」
とてもうれしい。今まで動いていたのは6809の命令だった。
今、動いたのは OS-9のCで書かれたプログラム である。
これは意味が違う。
違うプログラムを動かす。
次のSWI2が来る。
今度は別のサービスである。
そのシステムコールを実装する。
つぎのコードを実行する。
SWI2でまた止まる。未実装のコールだ。
その、システムコールを一個作る。
また次のコードへ進む。
息子が何しているの?
とくる。だーっと表示が出て、別ウインドウに何か出ているのを見せる。
同じ事をいくつかのテストコードでやっていたのだが、おもしろい。
このやり方は非常に分かりやすかった。
必要なものから作ればいい。
date -t などWindowsの該当コードから日付を作るだけである。
ところが、SWI2はサービス番号だけ分かればよいというものではない。
どのレジスタに何を入れて呼ぶのか。どのレジスタに結果が返るのか。
エラーが起きた時、何が返るのか。キャリーフラグはどうなるのか。
これが全部決まっている。
OS-9のプログラムは、その約束を当然知っている。こちらが間違えると動かない。しかし厄介なのは、すぐには止まらないこともある。
レジスタ一つを間違えて返す。その場では動く。数十命令進む。もっと進む。
そして全然関係なさそうなところで壊れる。
「何でここで落ちるんだ?」
逆アセンブラを見る。
レジスタを見る。
スタックを見る。
ログを見る。
戻る。
「あ、さっきのSWI2の戻り値が違う」
ということになる。
このCPUトレーサーなら、命令が正しいかを見ればいい。
OSを作るとなると、呼び出したプログラムが何を期待しているのかまで考えなければならない。
面白いけれど、急に難しくなった。だんだん複雑になった。
そのうち、当然のようにファイルを開こうとするプログラムが出てくる。
Open。
さて、困った。画面やキーボードの時は簡単だった。
OS-9プログラムはファイル名を渡してくる。こちらはWindowsで動いている。
では、Windowsのファイルを開けばいいのか。最初はそれでもよいかもしれない。だた、OS9のアプリケーションは大変である。エミュレーターの作者達がハードウエアのエミュレーターで済ませているのがよく分かる。
面倒な事は、昔のプログラムがやってくれるのだ。
OS9風にWindowsのファイルをエミュレーションして使うのは大変である。
おっくうになる。
また、OS-9のパス番号を管理するテーブルも必要になる。
ううん、知人はAIに作らせたらと言ってくる。へえそんなことが出来るのかと思った。
意を決して、ChatGPT君に尋ねてみる。意外や意外、いろんなサイトを検索し、出来そうだと答えてくれる。
今まで作ったコードを見せる。最新のプログラミングを知らない私のコードはANSI-Cである。
ざっとコードを読み、しばらくすると提案してくる。ものの数分だった。
この頃は、検索先を表示しながら見ているのを示す。CoCoのコードをみたり、雑誌のアーカイブを見たりしているようだ。検索先も参考になる。
.....
そして、上手く動いてしまった。
さて、OS-9には、標準入力、標準出力、標準エラーがある。
昔は普通に使っていた。UNIXとほぼ同等である。この設計の良さが分かる。
プログラムは「画面に文字を出す」のではない。
パスへ文字を書く。
だから、そのパスが画面でもいい。
ファイルでもいい。
パイプでもいい。
端末でもいい。
これは便利だ。
ゲームのシステムを作っていた時も、直接ハードウェアへ全部書くより、途中に共通の仕組みを作っておくと後で楽になる。
同じことである。
私のソフトでも、最初は標準出力をWindowsのコンソールへつないだ。
文字は出る。
ところが、本格的なOS-9ソフトを動かし始めると、それだけでは足りない。
カーソルを動かす。
画面を消す。
反転表示する。
入力を待つ。
エコーする。
制御コードを送る。
ここから、後で大仕事になる`/Term`の問題が始まるのだが、この時はまだ、
「そのうち端末処理も作らないとな」
くらいに思っていた。
なんたって、ChatGPT君が大幅に手伝うのだから、簡単だろうと
甘かった。(笑)
日本のOS-9の資料は、多分我が蔵書の方が充実しているのである。
ネットの世界は、タンディカラーコンピューターのコードばかりである。
該当の本をこちらが読んで教えなければいけない。対話型AIのなかなかしんどいところだ。あるとき、写真を貼り付け読ませてみた。解読するではないか。
本をスキャナーで読み、AIに読ませることしばらく。かなり優秀になったのだが、スレッドが一杯になってしまった。引き継ぎスレッドで進める。
そうして、ある程度勉強してくれたので再開である。
SWI2のコードをある程度実装した。
OS9から引っ張ってきたプログラムを実験で一つ動かす。
エラーがでる。
必要なF$を作る。
必要なI$を作る。
という感じで、少しずつサービスが増えていく。
F$Link。
F$Load。
F$Fork。
F$Wait。
F$Exit。
I$Open。
I$Read。
I$Write。
I$Close。
GetStt。
SetStt。
当然、一つ作るたびに、その裏側の仕組みが必要になる。
F$Forkを作るなら、プロセスというものを考えなければならない。
F$Linkを作るなら、モジュールというものを考えなければならない。
I$Openを作るなら、ファイルシステムとパスを考えなければならない。
I$Readを作るなら、ファイル位置を持たなければならない。
ChatGPT君の間違いも相当ある。
気がつけば、
「SWI2をが動けば簡単だろう」
から、
「OS-9の仕組みを作らないと動かない」
へ変わっていた。
ChatGPT君も、最初は、呼び出したプログラムをそのまま関数のように動かせばいいかな、という程度のコーディングだった。
AというプログラムからBを呼ぶ。
Bを実行する。
終わったらAへ戻す。
単純である。
しかし、OS-9はそういうOSではなかったのだ。
親プロセスがある。
子プロセスがある。
パスを継承する。
カレントディレクトリも持つ。
実行ディレクトリもある。
終了コードを返す。
待つ。
さらに、本来はマルチタスクである。
ここを適当に作ると、後で困るのは目に見えている。
シェル。
パイプ。
バックグラウンド。
マンハッタンならCP/Mとの並行動作。
全部ここにつながる。
ChatGPT君も、なかなか怖がって、一気に進化したコードを提案してくれない。
私は昔、Manhattanシステムと言うものを使っていた。
CP/M側でコンパイルしている時に、OS-9側で別の作業ができる。
それが便利だったのである。
ならばNEO MANHATTANでも、最終的にはそこまで持っていきたい。
プリエンプティブ・マルチタスク。
これは後回しにはする。
しかし、最初から「最終的には必要」と決めておいた。
マンハッタンの仕組みを載せたいと思ったが、同じ仕組みをWindows側で作るのは大変である。6809から切り替え動かすだけだから、切り替えさえ上手く動けば、という甘い考えである。
Z80のエミュレーションは、なんとChatGPT君に作らせた、あっという間であるい。そしてマンハッタンの回路図はないが、資料は沢山ある。どんなI/Oポートがあったのかも分かっている。
件のFM-11シミュレータに載るかChatGPT君に尋ねてみた。多分載るだろうと言う答えだが、まだOS-9の仕組みもええ加減な知識のChatGPT君には難しそうである。
マンハッタンのマスターディスクを発掘し、イメージ化した。今まで、FM-11シミュレーターでは動かないから、イメージ化していなかったのだ。40年前の 5インチ2HDディスクである。PC9821用の5インチ外付けが上手く動いてくれたので読み出せた。PC9821のWindws95から、LAN経由で持ってきた。そのほか、OS9時代のの5インチディスクも何枚もあるので、読み出した。そして5インチドライブはつぶれた。
ともかく、これでマンハッタンやら、Vterm40やら色々なソフトが復活した。
FM-11シミュレータで確認して動くテストプログラムもふえた。
SedのソースやYshのソースもありがたかった。これで、昔の環境が使えるのである。
というわけで、プログラム再開である。
OS-9らしいものの一つが、モジュールである。
実行プログラムもモジュール。
ドライバもモジュール。
ファイルマネージャもモジュール。
OSの部品もモジュール。
名前がある。
サイズがある。
タイプがある。
属性がある。
Revisionがある。
Editionがある。
CRCがある。
そして、メモリにロードされたモジュールはModule Directoryで管理される。
この仕組みは、今改めて見ると面白い。
ゲームの基本システムを作る時も、共通部分とデータを分ける。
必要なものを差し替えられるようにする。
OS-9はもっと本格的だが、発想としては分かる。
しかも、同名モジュールが複数ある場合、より新しいRevisionやEditionを優先したい。
新しいものをUNLINKして不要になったら、古いものがまた使える。
これも面白い。
「よし、ここもちゃんとやろう」
となる。
こういうところで、私の「ツール屋」の癖が出る。
単に動けばいい、ではなく、
あとで使いやすい形にしたくなる。
OS-9では、複数のモジュールを一つのファイルにまとめておくことができる。
たとえばutilityという一つのファイルの中に、
Attr。
Date。
Dir。
List。
Pwd。
など、いくつものモジュールが入っている。
実機のOS-9 Level IIでは、こういうロード単位とメモリページの割り当てが関係する。
しかしこのソフトでは、FM-11そのものを完全再現するわけではない。
Windows上で動くのだからメモリはたくさんある。
ならば、マージファイル全体を保持しておいて、必要なモジュールだけ論理空間に配置する方が便利ではないか。
ここで一つの考え方が出てきた。
「実機と同じでなければならないところと、現代的に改良してよいところを分けよう。」
昔のソフトが正しく動く。OS-9の考え方は壊さない。
でも、40年前のハードウェア制約まで全部背負う必要はない。
NEO MANHATTANは、FM-11のコピーではない。
名前の通り、「NEO」なのである。と意気込みは高い。
SWI2を一つずつ作る。
動かす。
止まる。
調べる。
直す。
また動かす。
これを繰り返す。
そして純正のDIRやDSAVEプログラムが最後まで走った。
メモリーをOSから確保し、RBFファイルのイメージをオープンして、
先頭から読み、たどり、順にディレクトリを読みファイル名を出す。
そういうプログラムである。
まあ、いくつかは未実装のSWIコールもあり、適当にごまかして走っているが、これはかなりうれしかった。
6809エミュレータが動いた時とは違う。
ここまで来ると、次にやりたいことは決まっている。
昔のOS-9ディスクを、読むだけでなく、そのまま使いたい。
Windowsへ取り出したファイルを一個ずつ使うのではなく、
/d0
/d1
/h0
と、昔のように見たい。
/D0/CMDSは
/D0/SYS
と、DIRコマンドで見えるもの自体を読み出したい。
昔のエディタを起動したい。
昔のCコンパイラを動かしたい。
Manhattanのモジュールを読みたい。
先にフロッピー救出作戦の最初は試行錯誤で困ったが、本を発掘すると、
FM77用のマニュアルに載っていたのだ。
そして、昔のCソースも発見した。
こうしてファイル抽出プログラムが、抽出したソフトをエミュレーターで実行できる様になった、偽OS9Shell ぽくなったのだ。
CPUエミュレータが付いて、OS-9互換実行環境がどんどん進化している。
OS-9の標準的なディスクファイルシステムは、RBFという。
しかし、その構造は、簡単ではなかった。
LSN0。
ディスク記述情報。
アロケーションビットマップ。
ファイルディスクリプタ。
セグメントリスト。
ディレクトリエントリ。
OS-9特有のファイル名表現。
そして、HDDなどは、物理ディスク構成がいろいろある。
FM-11のディスク。
5インチ2Dや2HD
エミュレーターで使われている。D77・D88は、今更ながらに面倒だが、このツールが多い。
RAWは簡単だが、これはない。自作で作るしかない。
これらを壊さないように安全に扱うには、ファイルシステムとディスクイメージ形式を分けて考えなければならない。
ファイルダンプエディターはBzエディターという便利なソフトがあった。
これで、HDDなどの何十メガのファイルを扱える。
読むのは簡単で、書くのは怖いのがディスクイメージ対応である。
次回 第三章は このお話です。
OS-9を再現していくと、WindowsやMS-DOSとは違う独特の設計に出会う。
その一つが、作業ディレクトリと実行ディレクトリの分離だった。
環境変数で PATH= としているのが、実行モジュールを探す場所である実行ディレクトリに相当する。
データファイルを探す場所がカレントディレクトリーであるが、実行プログラムはここにはおけないのである。
OS-9では、それらを分けて持つことができる。
CHD データディレクトリ
CHX コマンドディレクトリ
と指定する。
後にNEO MANHATTANでは、OS9のとおり、
PWD
はデータ用ワーキングディレクトリを表示し、
PXD
は実行用ディレクトリを表示する、
という形を明確にすることになる。
この違いは小さな仕様に見える。
また、CP/Mの A B C D E F
ドライブにハードディスクのフォルダーを
指定しなければうまく動かないのだ。
しかし、古いOS-9プログラムを動かすときには重要だった。
当時のソフトウェアは、その前提で作られている。
だからNEO MANHATTAN側が現代的な感覚で勝手に一つへまとめると、不思議な不具合が起きる。
こうした細かな仕様を一つずつ見直す作業が続いた。




