#contents

資料が少なく、間違っている場合もあるかと思います。~
間違っている部分を発見した場合は、コメント欄などにて指摘してもらえると嬉しいです。~
~

* VESA General Timing Formula (GTF) と Coordinated Video Timings (CVT) 
日本語で分かりやすいものが見つからなかったのでそのうち整理して簡単に使えるようにしたい。~
(これらの本当の資料は無料ではないらしいので無料で分かる範囲で。)~
~
-http://www.vesa.org/
--本家


-http://gtf.sourceforge.net/
--Linux GTFコマンドのソースが置いてある

-http://www.uruk.org/~erich/projects/cvt/
--同じくCVTコマンドのソースが置いてある

-http://www.vesa.org/Public/GTF/GTF_V1R1.xls
--GTFスプレッドシート: 表計算を使っているだけあって解像度の値を変えるだけでパラメータらしいものが再計算される。

-http://www.vesa.org/Public/CVT/CVTd6r1.xls
--CVTスプレッドシート: 上に同じ。

-http://www.delorie.com/djgpp/doc/rbinter/ix/10/4F.html
--参考になりそうなVESA関係のAPIリスト

** xlsファイルとC/C++ソースから読む タイミング算出方法
分かったことまとめ(書きかけにつき誤情報の可能性あり)~

-なし

** 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,133417000,7502,0>
構造体(CRTCInfoBlock)についてはこちら。
** 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
~
リフレッシュレートを0.01Hz単位でCRTCInfoBlock->RefreshRateにセットしておく(59.94Hzなら5994をセット)。~
%%他の部分の値はこの設定では無視されるので問題なし。%%→全然無視されないみたい? テスト環境(RIVA TNT2)のせい?~
RefreshRate以外を0にして呼び出してみたら見事にNo Signal(ディスプレイに入力が無いと表示される)…~
試しに下記のサンプルパラメータで呼び出してみたら見事にその解像度で出力されてる・・・!?(これはこれでちょっと嬉しいw)~
~
もしかして別のファンクションでパラメータを取得してリフレッシュレートだけ書き換えて呼び出さないといけないのかも知れない。~
(ちゃんと仕様書読まないとダメだなぁ・・・。)~
~
*** 既定の画面モードにない解像度設定に変更する
画面モード番号に81FFhを使用して画面モードを切り替える。~
上記と同様に構造体にあらかじめ信号のパラメータをセットしておき、そのアドレスをES:DIに入れて呼び出す。
 例:	mov	bx, 81FFh
 	push	cs
 	pop	es
 	mov	di, offset CRTCInf
 	mov	ax, 4F02h
 	int	10h
 
 ;	(中略)
 CRTCInf	CRTCInfoBlock	<1904,1520,1672,934,903,909,4,133417000,7502,0>
 ;※もしかしたら4F0Bhファンクションを使用してピクセルクロックを補正する必要があるかも知れない。
CRTCInfoBlock->Flagsにセットするフラグの意味はこちら。
-CRTInfoBlock->Flags の値と意味について
|ビット番号|ビット位置|>|LEFT:フラグ(を立てた時)の値と意味|
|0|0001b|>|LEFT:ダブルスキャンを有効にする(グラフィックモード)|
|1|0010b|>|LEFT:インタレースモードにする(グラフィックモード)|
|2|0100b|>|LEFT:水平同期信号の極性|
|~|~|0|LEFT:ポジティブ(+)|
|~|~|1|LEFT:ネガティブ(-)|
|3|1000b|>|LEFT:垂直同期信号の極性|
|~|~|0|LEFT:ポジティブ(+)|
|~|~|1|LEFT:ネガティブ(-)|
ちなみに、画面モード番号とフラグについてはこちら。
~
-画面モード設定とフラグの値と意味について
|ビット番号|ビット位置|>|LEFT:ビットの値の意味|
|8~0|0000 0001 1111 1111b|>|LEFT:画面モード番号(6Ahや102hなど)|
|10~9|0000 0110 0000 0000b|>|LEFT:予約済(0にする)|
|11|0000 1000 0000 0000b|>|LEFT:リフレッシュレート|
|~|~|0|LEFT:既定のリフレッシュレート|
|~|~|1|LEFT:CRTCInfoBlock->RefreshRateで指定するリフレッシュレート|
|~|~|1|LEFT:CRTCInfoBlockで算出されるリフレッシュレート|
|13~12|0011 0000 0000 0000b|>|LEFT:予約済(0にする。VBE/AF用)|
//|?|0010 0000 0000 0000b|>|LEFT:カスタムディスプレイタイミング使用フラグ?(動作せず。CRTCInfoBlock->Flagsの方なのか?)|
//|~|~|0|LEFT:既定のディスプレイタイミング|
//|~|~|1|LEFT:CRTCInfoBlockのディスプレイタイミング|
|14|0100 0000 0000 0000b|>|LEFT:フレームバッファの設定|
|~|~|0|LEFT:ウィンドウ|
|~|~|1|LEFT:リニア/フラット|
|15|1000 0000 0000 0000b|>|LEFT:フレームバッファのクリア|
|~|~|0|LEFT:する|
|~|~|1|LEFT:しない|
~
-ディスプレイタイミング
 画面外のディスプレイ信号について(自分用)                                             
 ━━━━━━━━━━━━━━━━━━━━                   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
これは基本なのであえて説明はしない。~
~
基本は上記(リフレッシュレート指定)とほぼ同じで、CRTCパラメータも一緒にセットしておく。~
セットするべきパラメータの基準は上記GTFやCVT、他のサイトなどを参考にすると良いだろう。~
*** 既定の画面モードのリフレッシュレートを変更する
画面モードを設定する際に該当するビットを立て、リフレッシュレートを定義したバッファ(構造体)のポインタを指定して切り替える。~
これで設定するとディスプレイに送られる信号は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)については上記参照。
~
(このまま実行するとVBEがエラーを返してきたので、やっぱり何か自前に準備する必要があるみたい。~
 そりゃあ、アクティブピクセル数の設定が無いのに単独で呼び出しても使えないよね・・・。)~
//リフレッシュレートを0.01Hz単位でCRTCInfoBlock->RefreshRateにセットしておく(59.94Hzなら5994をセット)。~
//%%他の部分の値はこの設定では無視されるので問題なし。%%→全然無視されないみたい? テスト環境(RIVA TNT2)のせい?~
//RefreshRate以外を0にして呼び出してみたら見事にNo Signal(ディスプレイに入力が無いと表示される)…~
//試しに下記のサンプルパラメータで呼び出してみたら見事にその解像度で出力されてる・・・!?(これはこれでちょっと嬉しいw)~
//~
//もしかして別のファンクションでパラメータを取得してリフレッシュレートだけ書き換えて呼び出さないといけないのかも知れない。~
//(ちゃんと仕様書読まないとダメだなぁ・・・。)~

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に入れて呼び出すのだろう。
// 例:	mov	bx, 81FFh
// 	push	cs
// 	pop	es
// 	mov	di, offset CRTCInf
// 	mov	ax, 4F02h
// 	int	10h
// 
// ;	(中略)
// CRTCInf	CRTCInfoBlock	<1904,1520,1672,934,903,909,4,133420000,7502,0>
// ;※もしかしたら4F0Bhファンクションを使用してピクセルクロックを補正する必要があるかも知れない。
//CRTCInfoBlock->Flagsにセットするフラグの意味と画面モードフラグは上記参照。
~
//基本は上記(リフレッシュレート指定)とほぼ同じで、CRTCパラメータも一緒にセットしておく。~
//セットするべきパラメータの基準は上記GTFやCVT、他のサイトなどを参考にすると良いだろう。~
~
(そのうち追記予定)
2008年4月10日追記: 検索から来られる人が意外と多いので追記します。&br;現在VESA3.0に対応したグラボを使用しているPCをweb鯖として使用しているため、実質的に確認することができなくなってしまいました。なので間違った(=正常に動作しない)まましばらく放置することになります。申し訳ありません。(やっぱり日本語に訳された資料が欲しい・・・)
//2008年4月10日追記: 検索から来られる人が意外と多いので追記します。&br;現在VESA3.0に対応したグラボを使用しているPCをweb鯖として使用しているため、実質的に確認することができなくなってしまいました。なので間違った(=正常に動作しない)まましばらく放置することになります。申し訳ありません。(やっぱり日本語に訳された資料が欲しい・・・)
~
この他にも、BytesPerScanLineやDisplayStartAddressなどを設定する必要があるかも知れない。~
しかし、色数(color depth)の設定やアクティブピクセル数の設定などは一体どこで設定するのだろう。~
~
** あとがき
リフレッシュレート指定でもCRTCInfoBlock->HorizontalSyncStartなどが有効みたいなので、液晶ディスプレイなどで画面の中央にドットバイドットで表示させたり、最大解像度より広い解像度を設定してその中を部分的に表示(ズーム?)する仮想解像度のような機能なら実現できるかも知れません。~
が、やっぱり自作系OSでも 1920x1080 とか 1680x1050 とか 1440x900 とか 1280x720 とか 960x720 などの解像度を使用したいなぁ…。~
~
SIZE(7){(無料で手に入る資料じゃ無理があるんだろうか・・・)}~
~
** コメント欄 [#commentarea]
ご意見やご感想、情報提供などお待ちしております。~
VBE 3.0関係の情報は少ないため、情報の提供は歓迎です。~

#comment

[Reload]   [New] [Edit] [Diff] [Upload]   [Front page] [List of pages] [Search] [Recent changes] [Backup]   [RSS of recent changes]