資料が少なく、間違っている場合もあるかと思います。
間違っている部分を発見した場合は、コメント欄などにて指摘してもらえると嬉しいです。
VESA General Timing Formula (GTF) と Coordinated Video Timings (CVT)
日本語で分かりやすいものが見つからなかったのでそのうち整理して簡単に使えるようにしたい。
(これらの本当の資料は無料ではないらしいので無料で分かる範囲で。)
xlsファイルとC/C++ソースから読む タイミング算出方法
分かったことまとめ(書きかけにつき誤情報の可能性あり)
VBE関係資料
- CRTInfoBlock
CRTCInfoBlock struc
HorizontalTotal dw ? ; Horizontal total in pixels
HorizontalSyncStart dw ? ; Horizontal sync start in pixels
HorizontalSyncEnd dw ? ; Horizontal sync end in pixels
VerticalTotal dw ? ; Vertical total in lines
VerticalSyncStart dw ? ; Vertical sync start in lines
VerticalSyncEnd dw ? ; Vertical sync end in lines
Flags db ? ; Flags (Interlaced, Double Scan etc)
PixelClock dd ? ; Pixel clock in units of Hz
RefreshRate dw ? ; Refresh rate in units of 0.01 Hz
Reserved db 40 dup (?) ; remainder of ModeInfoBlock
CRTCInfoBlock ends
- CRTInfoBlock->Flags の値と意味について
ビット番号 | ビット位置 | フラグ(を立てた時)の値と意味 |
0 | 0001b | ダブルスキャンを有効にする(グラフィックモード) |
1 | 0010b | インタレースモードにする(グラフィックモード) |
2 | 0100b | 水平同期信号の極性 |
0 | ポジティブ(+) |
1 | ネガティブ(-) |
3 | 1000b | 垂直同期信号の極性 |
0 | ポジティブ(+) |
1 | ネガティブ(-) |
- 画面モード設定とフラグの値と意味について
ビット番号 | ビット位置 | ビットの値の意味 |
8~0 | 0000 0001 1111 1111b | 画面モード番号(6Ahや102hなど) |
10~9 | 0000 0110 0000 0000b | 予約済(0にする) |
11 | 0000 1000 0000 0000b | リフレッシュレート |
0 | 既定のリフレッシュレート |
1 | CRTCInfoBlockで算出されるリフレッシュレート |
13~12 | 0011 0000 0000 0000b | 予約済(0にする。VBE/AF用) |
14 | 0100 0000 0000 0000b | フレームバッファの設定 |
0 | ウィンドウ |
1 | リニア/フラット |
15 | 1000 0000 0000 0000b | フレームバッファのクリア |
0 | する |
1 | しない |
- ディスプレイタイミング
画面外のディスプレイ信号について(自分用)
━━━━━━━━━━━━━━━━━━━━ H.Active
H.Active : H.Backporch ├─────┤ H.Frontporch
├─────┤ : ├-┤ ├-┤
┬┌─────┐──┐┬ : ┌────────┐┬ ┬V.Back
││//////////│ ││ : ┬│ ┌─────┐ ││ ┴ porch
V.Active││/表示画面/│ ││ : V.Active││ │//////////│ ││
││//////////│ ││V.Total : ││ │/表示画面/│ ││V.Total
┴└─────┘ ││ : ││ │//////////│ ││
│ ブランク・Sync ││ : ┴│ └─────┘ ││ ┬V.Front
└────────┘┴ : └────────┘┴ ┴ porch
├────────┤ : ├────────┤
H.Total : H.Total
VBE用ディスプレイタイミングのイメージ図 (自分用)
━━━━━━━━━━━━━━━━━━━━━━━━
ライン フロント バック
描画開始 ポーチ ポーチ
↓ )) ├───┤ ├───┤
┌────((────┐ ┌───┐ ┌────── ※信号の高低
信号 │//////// )) //////│ │ 同期 │ │(次のライン) はイメージ
─┴…………((…………┴───┘ 信号 └───┴……………… です。
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
├────-))-───────────────┤ ← HorizontalTotal
├────((────┤ ← HorizontalActive
├────-))-───────┤ ← HorizontalSyncStart
├────((────────────┤ ← HorizontalSyncEnd
※垂直方向も同様に。
GTFやCVTなどをVESA BIOS Extensionで設定する方法
いわゆるMS-DOS等リアルモードOSからVGA BIOSを呼び出して設定する方法です。
VGA(VESA)BIOSの都合上、VBE3.0以上の必要があります。
まずは基本
VBEファンクション02hを使用して画面モードを切り替える。
例: mov bx, 0102h ; ←画面モード番号
mov ax, 4F02h ; ←Set VBE Modeファンクション
int 10h
これは基本なのであえて説明はしない。
既定の画面モードのリフレッシュレートを変更する
画面モードを設定する際に該当するビットを立て、リフレッシュレートを定義したバッファ(構造体)のポインタを指定して切り替える。
これで設定するとディスプレイに送られる信号はGTF基準となる。
例: mov bx, 0902h ; ←モード番号とフラグ
push ds
pop es
mov di, offset [CRTCInf] ; ES:DI←構造体へのポインタ
mov ax, 4F02h ; ←Set VBE Modeファンクション
int 10h
; (中略)
CRTCInf CRTCInfoBlock <1904,1520,1672,934,903,909,4,133420000,7502,0>
構造体(CRTCInfoBlock)については上記参照。
CRTCInfoBlock->RefreshRateはBIOSでは使用されず、HorizontalTotalとVerticalTotal、PixelClockから算出されたリフレッシュレートが使用されるようです。
リフレッシュレートの計算方法は以下のようになっています。
PixelClock
refreshRate = ─────────────────
HorizontalTotal×VerticalTotal
例えば1024x768の画面モードではHTotalが1360、VTotalが802、正規化されたピクセルクロックが65MHzだとすると、このようになります。
65,000,000
refreshRate = ─────── = 59.59 Hz
1360× 802
既定の画面モードにない解像度設定に変更する
画面モード番号に81FFhを使用して画面モードを切り替える。が、まだよく分かっていません。
上記と同様に構造体にあらかじめ信号のパラメータをセットしておき、そのアドレスをES:DIに入れて呼び出すのだろう。
(そのうち追記予定)
この他にも、BytesPerScanLineやDisplayStartAddressなどを設定する必要があるかも知れない。
しかし、色数(color depth)の設定やアクティブピクセル数の設定などは一体どこで設定するのだろう。
あとがき
リフレッシュレート指定でもCRTCInfoBlock->HorizontalSyncStartなどが有効みたいなので、液晶ディスプレイなどで画面の中央にドットバイドットで表示させたり、最大解像度より広い解像度を設定してその中を部分的に表示(ズーム?)する仮想解像度のような機能なら実現できるかも知れません。
が、やっぱり自作系OSでも 1920x1080 とか 1680x1050 とか 1440x900 とか 1280x720 とか 960x720 などの解像度を使用したいなぁ…。
(無料で手に入る資料じゃ無理があるんだろうか・・・)
コメント欄
ご意見やご感想、情報提供などお待ちしております。
VBE 3.0関係の情報は少ないため、情報の提供は歓迎です。