DEMUプロジェクトの仕様と詳細 †
このページは、DOSエミュレータ 「DEMU」の仕様や進行状況を更新するページです。
最初から書き直す必要に迫られたので、改名とともにページ名を変更しました。
とりあえずDOS互換だけ実装し、その後コツコツと仕上げていくつもり。だいぶ完成してきました
大まかな骨組みは「基礎ライブラリ(グラフィックテキストボックス+ファイルアクセス/リスト+DOSメモリ管理)+CPU本体+APIシミュレータ」な予定。
(編集中)
もくじ
スクリーンショットとか †
最新 †
|
ファイル読み書き関係をちゃんと実装してOSASK上にファイルを作成できた。 とりあえずFM音源音色エディタが正常に動作するようになったのでここら辺で配布する予定。 |
|
とりあえずファイル読み込み関係を実装中。 今の段階では存在するファイルを読み込もうとすると応答無しになる。 |
|
実機のI/Oをアクセスするように変更しました。 FM音源音色エディタならファイルアクセスしなければ普通に動作します。 |
- コンソール出力ファイル(テキスト)
- コンソール出力ファイル(実行形式)
- COM化したテキストファイルです。なお、WinXP(2k含む)上で動作させるにはCONFIG.NTにANSI.SYSを追加する必要があります。
仕様とか †
内部資料(仮仕様) †
- グラフィックテキストボックス
- ヘッダ
_grp_id 8byte 識別用ID
_grp_prev dword 未使用_
_grp_next dword 未使用_
_grp_window dword 配置先ウィンドウ_
_grp_buffer dword 未使用_
_grp_left dword ウィンドウ内での座標_
_grp_top dword
_grp_scrnwidth byte 描画先の領域のサイズ(pixel)
_grp_scrnheight byte
_grp_fontwidth byte フォントのサイズ(pixel)
_grp_fontheight byte
_grp_textwidth byte バッファのテキスト単位のサイズ_
_grp_textheight byte
_grp_scaleleft byte 描画開始位置(テキスト単位)
_grp_scaletop byte
_grp_width byte 描画先のテキストサイズ(テキスト単位)
_grp_height byte
_grp_cursor_x byte コンソール出力用の座標(x,y)
_grp_cursor_y byte
_grp_color_fl byte 文字色(16色)
_grp_color_bg byte 背景色(16色)
_grp_cursor_sav 4bytes カーソル位置待避用_
_grp_escseqflag byte エスケープシーケンス継続フラグ_
_grp_escseqcnt byte パラメータ保存数_
_grp_escseqcmd byte エスケープシーケンスコマンドバイト_
_grp_escseqval byte パラメータバッファ(1個1バイト)
_grp_escseqsize = 3 パラメータバッファのサイズ(定数)
(残り) 未使用_
- 内部バッファ
以下の8byteが文字数分(80x25=半角2000文字分=16000byte)連続する。
テキストコード(32bit) 4byte
文字色 1byte
背景色 1byte
拡張用 2byte
テキストにしてはメモリを使用するなぁ。
- テキスト関係APIの実装状態(未実装/実装作業中/実装済み)
- グラフィックテキストボックスオープン
; in: edx ウィンドウ
; esi,edi グラフィックボックスの位置
; cl,ch テキストボックスの表示領域のサイズ
; al,ah テキストボックスのバッファのサイズ
; ebx グラフィックテキストボックス
- グラフィックテキストボックスフォント関連
- グラフィックテキストボックス色深度関連
- グラフィックテキストボックス解像度またはリサイズ関連
- MCBのとは?
DOS上でメモリを管理する仕組み。
DOSはメモリをリサイズや開放などをするとき、メモリセグメントの1パラグラフ前にくっついているこのMCBを変更するというのが実体です(もちろんチェイン先にMCBを書かなくてはいけません)。
- MCBの実装について
現在はDOSアプリが最初のメモリブロックの位置を取得することはできません。
DEMUがメモリブロックのリサイズや新規確保に対応するために実装します。
- 最初のMCBは
0x0BFFくらいとりあえず0x07FF
- 初期化で作成するMCBは空のメモリブロック(0x0800~0x9FFE)と将来のUMB用(システムが使用中のマーク)(0xA000~0xFFFF)の2つ。
- MCBの内容
; Memory Control Block セグメント
; ofs size document
; 0h byte チェインID(4Dhか5Ah)
; 1h word オーナーID(0:空き,8:DOS/システム,その他:確保したプログラムのセグメント?)
; 3h word サイズ(パラグラフ)
; 5h 3bytes reserved
; 8h 8bytes プログラム名(終端:00hまたはスペースで埋める)
- 内部変数領域のメモ
; 内部変数領域の割り当て
; ofs size document
; es:bx-12 word 共有リトライ回数(DOS 440Bh)
; es:bx-10 word 共有リトライデュレイ
; es:bx-8 dword カレントディスクバッファへのポインタ
; es:bx-4 word 未読み込みCON入力のDOSコードセグメント内のポインタ
; es:bx-2 word 先頭のMCBのセグメントアドレス
; es:bx dword 先頭のDPBへのポインタ
; es:bx+04h dword 内部FCBのリストを指すポインタ
; es:bx+08h dword CLOCKデバイスドライバへのポインタ
; es:bx+0Ch dword CONデバイスドライバへのポインタ
; es:bx+10h word 扱える最大のセクタのサイズ(byte/sector)(AT:512)
; es:bx+12h dword 内部ディスクバッファの先頭アドレス
; es:bx+16h dword 内部ドライブ情報の先頭アドレス
; es:bx+1Ah dword reserved
; es:bx+1Eh word FCBS=x,y の y
; es:bx+20h byte 接続ドライブ数
; es:bx+21h byte LASTDRIVEドライブ数(LASTDRIVE=Zなら1Ah)
; es:bx+22h 18bytes NULデバイスのデバイスヘッダ
; es:bx+34h byte JOINドライブ数
; es:bx+35h word reserved
; es:bx+37h dword reserved
; es:bx+3Bh word reserved
; es:bx+3Dh word reserved
; es:bx+3Fh word BUFFERS=x,y の x
; es:bx+41h word BUFFERS=x,y の y
; es:bx+43h byte ブートドライブ(1=A:,2=B:...)
; es:bx+44h byte =1:80386/486, =0:8086/286
; es:bx+45h word 拡張メモリ(1Mバイト以降のプロテクトメモリ)のサイズ(KB)
この内部変数領域をゲストOSメモリ上に置かなければならないのが以外と面倒。
- ファイル関係の整理
- ファイルハンドル→PSP内のローカルなハンドル→FCBの番号という変換は行わない。
- ファイルハンドル→16倍してOSASK側のスロットという直接な変換をする。
- 従ってゲストOS側に返されるファイルハンドルの値は0x20~0x3Fとなるが、実際はもっと狭い範囲になる(同時オープン可能なファイル数も制限される)。
- ファイルへの追記はサポートする。そのときの挙動はOSに任せる。新規作成でシーケンシャルなファイル書き込みを使用していると書き出しの度にリサイズしなければならないが、その都度OSへ任せないである程度キャッシュしたほうがいいだろうか、速度的に。
- DOSアプリ実行中のファイルアクセスは、OSASK側のモジュールをマッピングしてブロック転送するという方法を用いる。リサイズを伴う場合は先に一定のサイズを広げてからブロック転送する。そのとき、(リサイズでエラーが帰ってきたら書き込みエラーまたは書き込まれたサイズを小さくして正常終了する。
- (編集中)
- ファイルハンドル0~4(5?)にはまだ対応していない。
- ファイル関係のAPI
OSASKのFD上にはルートディレクトリしかないけど、どうしよう。
ルートディレクトリ以外へのアクセスはエラーにした方がいいのか、それともディレクトリ指定を無視した方がいいのか。
- ファイルオープン(AH=3C,3Dh)
- ファイルクローズ(AH=3Eh)
- 最初のファイル検索(AH=4Eh)
- 次のファイル検索(AH=4Fh)(現在は常にエラーを返す)
- ファイルの削除(AH=41h)(現在は常にエラーを返す)
ファイル検索や削除、属性関係はディスクイメージを扱うようになるまで正常な動作をしない。
- DOSファンクションのエラーコードのリスト
コード | 意味 | コード | 意味 |
01h | 無効なファンクションコード | 02h | ファイルが見つからない |
03h | パス名が見つからない | 04h | これ以上ファイルをオープンできない |
05h | アクセスできない | 06h | 無効なハンドル |
07h | MemoryControlBlockが破損している | 08h | メモリが足りない |
09h | メモリブロックのアドレスが無効 | 0Ah | 環境が無効 |
0Bh | 書式が無効 | 0Ch | アクセスコードが無効 |
0Dh | データが無効 | 0Eh | 予約 |
0Fh | ドライブ名が無効 | 10h | カレントディレクトリは削除できない |
11h | 同じデバイスではない | 12h | これ以上ファイルはない |
13h | ライトプロテクトされている | 14h | ディスクユニットが不良 |
15h | ドライブが準備できていない | 16h | ディスクコマンドが無効 |
17h | CRCエラー | 18h | 長さが無効 |
19h | シークエラー | 1Ah | MS-DOSのディスクではない |
1Bh | セクタが見つからない | 1Ch | 用紙がない |
1Dh | 書き込みエラー | 1Eh | 読み出しエラー |
1Fh | 一般的なエラー | 20h | 共有違反 |
21h | ロック違反 | 22h | ディスクが不正 |
23h | FCBは使用できません | |
32h | ネットワークリクエストが未サポート | 33h | リモートPCが待ち受け状態ではない |
34h | ネットワーク名が重複している | 35h | ネットワーク名が見つからない |
36h | ネットワークビジー | 37h | ネットワークデバイスはこれ以上ない |
38h | ネットワークBIOSの限界を超えた | 39h | ネットワークアダプタのハードエラー |
3Ah | ネットワークから不正な応答があった | 3Bh | 予期できないネットワークエラー |
3Ch | リモートアダプタが不正 | 3Dh | プリント待ち行列が満杯 |
3Eh | 待ち行列が満杯ではない | 3Fh | プリントファイルのためのスペースが不足 |
40h | ネットワーク名はすでに削除されている | 41h | アクセス不可能 |
42h | ネットワークデバイスのタイプが不正 | 43h | ネットワーク名が見つからない |
44h | ネットワーク名の限界を超えた | 45h | ネットワークBIOSセッションの限界を超えた |
46h | 一時休止 | 47h | ネットワークの要求が受け付けられない |
48h | プリンタ/ディスクのリダイレクト禁止 | 50h | ファイルが存在する |
52h | 作成不可能 | 53h | 割り込み24hのエラー |
54h | ネットワーク構造が不正 | 55h | 割り当て済み |
56h | パスワードが無効 | 57h | パラメータが無効 |
58h | ネットワークへの書き込みエラー | 5Ah | システム関連ファイルがロードされていない |
- キーボード入力関係の仕組み
- OSASK標準割り当てキーコード(キャラクタはそのまま、特殊キーは0x80~に割り当て)がシグナルとしてdefineしたものが送られてくる
- キーボードシグナルを受信すると同時にキャラクタコードとスキャンコードに変換してキーバッファに蓄える。
- デバッグコンソールやゲストOSが取得したときにそのキャラクタコードを渡す。そのキャラクタコードが0だった時のみ、次の取得でキースキャンコードを渡す(int21h 1文字入力ファンクション実行時)。
- マルチコンソールが有効なときは本来ならアクティブな方のキーバッファに送らないと誤動作する可能性があるが、今回は両方(デバッグコンソールとゲストOS)で共通のキーバッファを使用する(デバッグコンソールとゲストOSが同時に取得することはありえないため)。
- 特殊キー(矢印キーとかPageUpとか)が押された場合はDOS/V標準の00hが取得されてからキースキャンコードが取得される方式を採用。PC98式(TOWNSはまた違った気がする)は←キーとか0x08(BS)に割り当てられていたりするため、微妙に動かないだろう。
管理用メモ †
ここは、管理人が試行錯誤しながら変更していく内部用のメモがわりです。
- DEMU起動時に実行ファイルをオープン(関連付け起動対応)。
- メモリブロックの構造や環境変数などを内部(外部優先)ファイルを元に初期化
- DOS実行ファイルを(必要ならばリロケーションして)メモリに配置。
- 実行可能なEXEファイルにはサイズ制限があります(実際のEXEファイルのサイズが560KB未満)。
- ファイルの読み込みや書き出しは必要な場合のみ、ディスクイメージをアクセスする。
- 実行ファイルの位置はそのイメージ内にあるものとする。
- 実際にディスクイメージ内に無い場合でも内部的には微妙。
- ハードディスクやCD-ROM等はアクセスできない。
- BIOSをエミュレーションしているわけではないのでBIOSレベルの操作は正常に動作しない。
- 常駐するアプリは対応していない。というかコマンドラインが無いので正常終了と同じ扱い。
- タイマ割り込みをエミュレーションするかどうかは使っているアプリがどのくらいあるかによる。
- ゲストOS内の時間設定はとりあえず起動時に2006/11/13 17:30:00.00にセットしてみる。
- DOS Versionは5.0としようかな。
- 画面はテキストのみ。以下の解像度で表示。いわゆるANSI対応。
今のところテキストVRAMはDOSからアクセスできるメモリ上には無い。
現在の動作原理的には空きメモリ960KBも夢では無いけど、DOS汎用のアプリでそこまでメモリを使うものがあるのか?という疑問が。
モード | 解像度 | フォント | 表示解像度 | 言語 |
3 | 80x25 | 6x12 | 480x 300 | jp |
- | 80x30 | 6x12 | 480x 360 | jp |
3 | 80x25 | 6x12 | 480x 300 | us |
- | 80x30 | 6x12 | 480x 360 | us |
- | 80x25 | 8x16 | 640x 400 | - |
- | 80x30 | 8x16 | 640x 480 | - |
- | 80x25 | 12x24 | 960x 600 | - |
- | 80x30 | 12x24 | 960x 720 | - |
PCアーキテクチャはAT互換機(=DOS/Vではない)ということにして、グラフィックボードはモード03のみのCGAということにしてしまおうか。
VGAでもいいが、VGAはI/O描画周りが回りくどくて面倒そう。
それと一部のマシンでOSASKアプリで640x480のウィンドウをオープンできない問題がある。
- キーボード
- DOSファンクション経由のみ。多分同時押し検出不可能。
- マウスドライバ
- int 33hのエミュレーションをやればできそうだけど対応しているアプリが無さそうなので先送り。
- プリンタ
- ファイル
- ディスクイメージ起動ではないのでファイル検索は未対応。ファイル名を指定して開くことならできる。
- フロッピィディスクエミュレーションだけどネットワークドライブと考えれば(検索できないけど)イメージがあいそう。
- CPU/FPU
- 8086シリーズ。80386DX相当。PM/PG/VM/FPU/SSE/MMX/SSE2/SSE3/3DNow!非対応。32bitレジスタ対応。インタプリタ型。
- FPU命令を全く実装していないのでFPUの存在をチェックするようなプログラム(BASICやC言語などで作成されたものは怪しい)は動かせないと思われる。
- サウンド
- メモリ配置
- 起動するDOSアプリは0x00008000~0x0009FFEFを自由に使える。UMBやEMB、HMAは使えない(予定)。
- その他
(編集中)
進行状況欄 †
ここは管理人が書く場所です。
- ソースを書き直す段階になって、基礎ライブラリ再構築中。これのテスト中にテストゲームなどを作成するかもしれない。 -- nika 2006/09/28 (木) 06:23:43
- とりあえず、当初の計画に戻って、DOS APIレベル(int 21hレベル)のエミュレーションでDLL(デバイスドライバ)を使用しない形式で作成しようと思います。 -- nika 2006/10/11 (水) 04:02:59
- 6x12ドットの内蔵ASCIIフォントを使用する。日本語はOSASKシステムフォントを縮小して使用するつもり。16x16を12x12に縮小するにはHighColorなら中間色補間ができるが、16色だとそれもできない。16x16→12x12(単純補間(間引き)または適応補間)しかできない。 -- nika 2006/10/12 (木) 04:05:44
- ファイルアクセス関係実装中。 -- nika 2006/10/13 (金) 13:21:26
- 実行ファイルのリロケーションとかPSPの用意とか準備関係実装中。 -- nika 2006/10/14 (土) 18:14:13
- この方式(DOSAPIレベル)だとディスクイメージってわけにはいかないよなぁ。やっぱりリストファイル(alias可能な)を参照してそれをDOSディスクにしよう。セクタ単位のアクセスまでサポートしなくても(あるいは、簡単なサポートだけで)動作するだろうし。 -- nika 2006/10/14 (土) 23:23:59
- グラフィックボックスを使うのをやめて、独自のテキストVRAMみたいなものを使用する用に実装中。 -- nika 2006/10/17 (火) 16:59:20
- 独自のテキストボックス形式で疲れた。 -- nika 2006/10/18 (水) 19:50:59
- テキストボックス関係の実装は一通り完了。これからCPU部の実装(といっても旧バージョンのコピーに近いが)とかだな。 -- nika 2006/10/21 (土) 03:24:25
- CPUの実装の完了とEXEファイル関係、PSPや環境変数も完了(ほとんどの値は0ですが)。あとはDOSファンクションの実装、これだけ(OSASK側のファイルへのアクセスとか、そういう問題はある)。 -- nika 2006/10/22 (日) 08:36:14
- MCB(Memory Chain Block)の実装中。 -- nika 2006/10/22 (日) 21:16:22
- 風邪っぽい症状でなんか実装がはかどらなかった。なんかなんか言葉にしにくい…。こういうときサプリメントとか効くんだろうか・・・ -- nika 2006/10/24 (火) 14:01:34
- naskの最適化ルーチンにバグがあるようです。cmp [レジスタ + 定数], 値、のとき、定数が0だと不安定になるようです。 -- nika 2006/10/25 (水) 01:10:50
- 予定: カーソル位置を自作ライブラリメモリに確保してコンソール出力描画ルーチンをライブラリ化してマルチウィンドウでもコンソール出力が使えるようにする。そしてその別のグラフィックテキストボックスへゲストDOSアプリのレジスタのダンプとかデバッグメッセージなどを表示するようにする。 -- nika 2006/10/31 (火) 04:24:55
- naskのバグをMLに流しました。 -- nika 2006/11/04 (土) 01:35:16
- 久しぶりにちょっとずつ更新再開。デバッグウィンドウ(デバッグコンソール?)実装に入ります。 -- nika 2006/11/10 (金) 05:57:24
- キーボード入力の処理とシグナルハンドラを実装中。 -- nika 2006/11/10 (金) 15:47:11
- カーソル点滅のための毎秒18.2回のタイマとキーボード入力を引き続き実装中。デバッグコンソールから1命令のトレースとかできるようにするのはCPUルーチンの改造が必要だなぁ…。 -- nika 2006/11/11 (土) 15:04:54
- キー入力に関する仕様を追加。 -- nika 2006/11/13 (月) 14:39:15
- or命令実行後の値がおかしくなることがあるのを修正しました。キーボード入力周りを実装しました。 -- nika 2006/11/21 (火) 23:59:58
- xchg al, ahのとき、第2オペランドがSPの上位バイトになっていたのを修正しました。 -- nika 2006/11/22 (水) 15:39:54
- RTCのCMOS-RAMのメモリマップを追加 -- nika 2006/11/23 (木) 14:35:42
- ゲストOS内でのI/Oアクセスを(一部を除き)そのまま実機のI/Oをアクセスするようにすれば、fmeditとかqemu(のosask)上で動作できて、うまー? -- nika 2006/11/23 (木) 14:37:55
- それと、時間取得関係はとりあえず実機のRTCを取得してみて、正常に取得できなかったら自前に用意した日付/時刻をゲストOS側の時間にするつもり。 -- nika 2006/11/23 (木) 14:39:28
- QEMU上のOSASKではRTCがパックドBCDモードに設定されているようだ。 -- nika 2006/11/24 (金) 00:26:43
- 実機上のOSASKでもRTCがパックドBCDモードに設定されているようだ。そうなると、パックドBCD/バイナリモード自動判別(自動変換処理)ルーチンを実装しないといけないかな。 -- nika 2006/11/24 (金) 02:13:13
- qemuと実機でRTCのデータフォーマットを確認したが、どちらもRTCのCMOS-RAMのレジスタBのbit2=0でBCDで取得された。http://bochs.sourceforge.net/techspec/CMOS-reference.txtを見るとbit2=0:BCDとなっているので、とりあえずそのように(表示も実装も)修正しました。 -- nika 2006/11/26 (日) 16:05:26
- これをそのままPC98エミュレータ上で実行させたら、 473年90月 4日 4時35分 4秒と表示されてしまった。 -- nika 2006/11/26 (日) 16:23:17
- ゲストOS側の時刻は1秒単位で更新するように実装。ただし、手抜きな仕様により日付は更新されない(同じ日付を繰り返す)。 -- nika 2006/11/27 (月) 01:25:45
- DIV命令のオーバーフロー検出で、オペランドサイズが8/16bitの場合、誤検出することがあるのを修正。 -- nika 2006/11/27 (月) 01:27:12
- RTCのリードで、世紀情報(年の上位2桁BCD)が10~29以外の場合、用意してある日付/時刻を使用するように変更(でもI/OWriteするのでAT互換機以外では誤動作するかも知れない)。 -- nika 2006/11/27 (月) 01:30:56
- build: 2006/11/27版のDEMUを公開しました。 -- nika 2006/11/28 (火) 01:00:55
- RTCのCMOS-RAMアドレスマップを(AT)RTCへ移動させました。 -- nika 2006/11/28 (火) 19:45:32
- fmeditの動作速度改善のためには、垂直同期割り込み毎に差分だけを画面を更新するようにしないといけないだろうなぁ。あとは、ファイル関係のファンクションを実装すればfmeditも(OSASK上で)実用になるかな。 -- nika 2007/06/01 (金) 15:50:48
なにか書いていってください †
なんでもいいですよ。
- メモ: http://hp.vector.co.jp/authors/VA015412/colum/pe.htm -- nika 2006/10/15 (日) 16:08:06
- ぉ、いきなり進みましたねwwいいだけ逃げていたのにwwすげーな。応援してもります。 -- 通りすがりんこ 2006/10/17 (火) 21:28:22
- 応援ありがとうございます。OSCがあるのでそれまでには何とかアプリ実行できるまでにしたいです。 -- nika 2006/10/19 (木) 03:32:31
- メモ: http://forum.nifty.com/fpcu/dosvcmd/ansi.htm -- nika 2006/10/19 (木) 20:18:28
- メモ: http://www.imasy.or.jp/~i16/iroiro/dos_doc.htm -- nika 2006/10/22 (日) 08:37:56
- そういえばMt.orzはDOS汎用ではないから、動作検証には使えないなぁ(ATのBIOSに依存している)。DOS汎用版は無いのかなぁ。 -- nika 2006/10/24 (火) 06:39:33
- メモ: http://www.h3.dion.ne.jp/~unisoft/tiny001.html -- nika 2006/11/22 (水) 17:28:14
- ファイルapiの不備はRAMディスクドライバ的なものが動けばお茶を濁せないかなあ? -- 名無しさん 2007/06/23 (土) 14:58:13
- RAMディスクドライバ的なものですか…、DOSEmulator(仮)の方向性がハードウェアレベルだったときに投票で1.44MBの2HDベタイメージ(サイズが足りないところは不良扱い)ってことに仮定したんですけど、これとは違うものでしょうか? -- nika 2007/06/23 (土) 22:00:23
- 上を見るとアプリ側でのメモリの確保等は今でもある程度いけるみたいなので、DOS用の既存ラムディスクドライバ(例えばコンベンショナルメモリから確保するような)が組み込めないかなと思いまして。まあFDCとかATAをエミュった方が手っとり早いかもしれませんし、公式対応な例の(じゃなくてもだけど)アーカイブ形式なら検索とかも実装出来るかもしれませんが。 -- 名無しさん 2007/06/24 (日) 07:38:37
- うーんと、DOSのファンクション(int 21h)自体を再現する仕様ですのでドライバ等は組み込めない仕様です。OSASK上でアプリがファイルをオープンするとすべてが読み込まれキャッシュされてから制御が戻ってくるので、その辺はこれでいいかなと思ってます。アーカイブ形式のファイルの扱いの細かい仕様はどうなのか分かってません。そのうち調べてみたいですねぇ。 -- nika 2007/06/27 (水) 06:37:38