このページはBochsのBIOS(rombios.c)についてまとめたページです。
参考にしたバージョンは以下の通りです。
$Id: rombios.c,v 1.160 2006/01/25 17:51:49 vruppert Exp $
ただし、リンクは使用できません。URLに「#」がつくだけです。
BIOSが使用するデータバッファです。
最大でどのくらい使われるのか分かりませんが、大きくても40KB~63KBくらいでしょう。
640KBの低位メモリの高位(0x000A6000~0x000AFFFFなど)が使われます。
| RAMアドレス | 用途/意味 | 備考 |
| 0x10 | フロッピーディスクドライブのタイプ(high4bits:#0,low4bits:#1) | |
| 0x12 | ハードディスクタイプ(high4bits:#0,low4bits:#1) | |
| 0x19 | ハードディスク#0の拡張タイプ | 2Fh(47)固定? |
| 0x1A | ハードディスク#1の拡張タイプ | |
| 0x1B~23 | ハードディスクパラメータ#0 | |
| 0x24~2C | ハードディスクパラメータ#1 | |
| 0x2D | b5(0x20):CDブート非対応コンパイル時のブートシーケンス(=0:C,A/=1:A,C) | |
| 0x38 | 3rd(high4bits) boot device | 値の意味はこちら |
| 0x38 | FDブート時のboot signature disableの値(bit0) | =0:enable,=1:disable |
| 0x39~3A | ATA driver: the translation policy is defined | |
| 0x3D | 1st(high4bits)/2nd(low4bits) boot device | 値の意味はこちら |
| 値 | 意味 |
| 0 | デバイス未定義(終了?) |
| 1 | フロッピーディスクドライブ #0 |
| 2 | ハードディスクドライブ #0 |
| 3 | CD-ROMドライブ |
| コメント | お名前 | NameLink | |
static int int19_function(char bseqhr);
// リターン値: ax = BOOTセグメント, bl = ドライブ番号
Bit32u
int19_function(bseqnr)
Bit8u bseqnr;
{
Bit16u ebda_seg=read_word(0x0040,0x000E);
Bit16u bootseq;
Bit8u bootdrv;
Bit8u bootcd;
Bit8u bootchk;
Bit16u bootseg;
Bit16u status;
Bit8u lastdrive=0;
// BX_ELTORITO_BOOTをdefineしないでコンパイルした場合(古い方法)
// CMOS(0x2D)のbit5をDLのbit7にロードする.
// これはINT 13hの呼び出し時にセットされる(?)
// (0=フロッピーディスク A:, 0x80=HDD C:)
// 0: ブートする順番はC:が最初でその後にA:
// 1: ブートする順番はA:が最初でその後にC:
// BX_ELTORITO_BOOTをdefineしてコンパイルした場合
// CMOS(0x3Dと0x38)の内容で以下のように指定する
// CMOS(0x3D)の下位4bit : 1st boot device
// CMOS(0x3D)の上位4bit : 2nd boot device
// CMOS(0x38)の上位4bit : 3rd boot device
// boot device の割り当て:
// 0x00 : 未定義
// 0x01 : フロッピーディスク(A:)
// 0x02 : ハードディスク(C:)
// 0x03 : CD-ROM(D:)
// その他 : ブート中断
// ブートデバイスの順番を取得
bootseq=inb_cmos(0x3d);
bootseq|=((inb_cmos(0x38) & 0xf0) << 4);
// bseqhrはboot device の順番(1st/2nd/3rd)
if (bseqnr==2) bootseq >>= 4;
if (bseqnr==3) bootseq >>= 8;
if (bootseq<0x10) lastdrive = 1;
bootdrv=0x00; bootcd=0;
switch(bootseq & 0x0f) {
case 0x01: bootdrv=0x00; bootcd=0; break;
case 0x02: bootdrv=0x80; bootcd=0; break;
case 0x03: bootdrv=0x00; bootcd=1; break;
default: return 0x00000000;
}
// CDからブートすることができる場合
if (bootcd != 0) {
status = cdrom_boot();
// 失敗した場合
if ( (status & 0x00ff) !=0 ) {
print_cdromboot_failure(status);
print_boot_failure(bootcd, bootdrv, 1, lastdrive);
return 0x00000000;
}
// 成功した場合はセグメントとドライブ値を設定
bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
bootdrv = (Bit8u)(status>>8);
}
// ハードディスクかフロッピーディスクから起動する場合
if (bootcd == 0) {
bootseg=0x07c0;
ASM_START
push bp
mov bp, sp
mov ax, #0x0000
mov _int19_function.status + 2[bp], ax
mov dl, _int19_function.bootdrv + 2[bp]
mov ax, _int19_function.bootseg + 2[bp]
mov es, ax ;; segment ;; BootSegment:0x07c0
mov bx, #0x0000 ;; offset
mov ah, #0x02 ;; function 2, read diskette sector
mov al, #0x01 ;; read 1 sector
mov ch, #0x00 ;; track 0
mov cl, #0x01 ;; sector 1
mov dh, #0x00 ;; head 0
int #0x13 ;; read sector
jnc int19_load_done
mov ax, #0x0001
mov _int19_function.status + 2[bp], ax
int19_load_done:
pop bp
ASM_END
// 失敗した場合
if (status != 0) {
print_boot_failure(bootcd, bootdrv, 1, lastdrive);
return 0x00000000;
}
}
// CMOS(0x38)でフロッピーディスクブートが指定
// された場合のみ、signuatureをチェックする
// bootchk = 1 : signature check disabled
// bootchk = 0 : signature check enabled
if (bootdrv != 0) bootchk = 0;
else bootchk = inb_cmos(0x38) & 0x01;
// CDブート時はsignatureチェックをしない
if (bootcd != 0)
bootchk = 1;
if (bootchk == 0) {
if (read_word(bootseg,0x1fe) != 0xaa55) {
print_boot_failure(bootcd, bootdrv, 0, lastdrive);
return 0x00000000;
}
}
// 起動メッセージの表示
print_boot_device(bootcd, bootdrv);
// リターン値としてブートセグメントを返す
return (((Bit32u)bootdrv) << 16) + bootseg;
}
(書きかけ)
| IOアドレス(FDC#1/#2) | レジスタ名 | 読み書き | 意味 | 備考 |
| 3F0/370h | ステータスレジスタA | R | 本家ATには無い | |
| 3F1/371h | ステータスレジスタB | R | 本家ATには無い | |
| 3F2/372h | ディジタルアウトプットレジスタ | W | ||
| 3F3/373h | テープドライブレジスタ | RW | テープサポートが無ければ関係ない | |
| 3F4/374h | メインステータスレジスタ | R | ||
| 3F4/374h | データレートセレクトレジスタ | W | 本家ATには無い | |
| 3F5/375h | データレジスタ(FIFO) | RW | ||
| 3F7/377h | ディジタルインプットレジスタ | R | ||
| 3F7/377h | コンフィグレーションコントロールレジスタ | W |
FDCの動作は以下の3つのフェーズを経て行われます。
FDCがアイドル状態(MSR=80h)にあるとき, CPUはFDCへのコマンドの書き込みを開始できます.
コマンドは1~2バイトで, さらにパラメータが付いて最大9バイトを書き込みます.
パラメータの省略はできないので, 必ず必要なバイト分すべてを書き込みます.
コマンドの書き込みはMSRのRQM = "1", DIO = "0"を確認しながら行います.
もしFDCがコマンド異常を検出すると, 最後のリザルトフェーズに移行しますが, このときにはDIO = "1" となるので, 異常発生がわかります.
コマンドフェーズが終了すると, FDCはエグゼキューションフェーズに移行します. 例外は,
・SENSE INTERRUPT STATUS(直接リザルトフェーズに移行)
・SENSE DEVICE STATUS(直接リザルトフェーズに移行)
・SPECIFY(コマンドフェーズだけで終了)
などのFDDへのアクセスが不要なコマンド群です.
コマンドを受け取ると, FDCはエグザキューションフェーズに移行します.
FDのリード/ライトや, ヘッドシーク(ヘッドの移動)などが行われます.
DMAモードに設定していれば, FDのリード/ライト系コマンドのエグゼキューションフェーズでDMA転送要求が行われます.
PCの場合, FDCとのデータ転送は, DMAを用いて行うのがふつうの使い方です.
エグゼキューションフェーズが完了すると, 通常FDCはリザルトフェーズに移行するとともにホストに割り込みをかけます.
例外はSEEKやRECALIBRATE(0トラックへのシーク), RELATIVE SEEKです.
これらはRフェーズがないので, 動作完了後に割り込みが発生した後, SENSE INTERRUPT STATUSコマンドを発行して結果を引き取ります.
コマンドの実行結果ステータスを通知するのがこのフェーズです.
コマンドの種類に応じて1~7バイトのステータスを引き取ります.
リザルトフェーズでは1バイトの転送ごとにMSRのRQMが "1" になり, またDIOビットは "1" になっています.
ステータスはすべて引き取らないと, 次のコマンドが発行できません.
ステータスが残っているときはDIO = "1", すべて引き取るとDIOビット="0"となるので, ステータスの引き取りが完了したかを判断することができます.
| コメント | お名前 | NameLink | |