雑記帳
ここはhideyosiの雑記帳です。テケトーに書き散らしてるだけなので間違っていたりとは普通にしてます。信用度は相当低いことをあらかじめご了承を。またご覧のようにWikiを使ってますが、hideyosi意外は書き込めません。

えとえと、VGAという単語そのものはいろいろと意味がありそうですが、ここでは640x480x16色のモードのことということで・・・

プレーン方式 anchor.png

VGAはどうもこのプレーン方式というものらしい。つまり、ひとつのドットがひとつの値というのではなく、プレーンという何枚かあるセル(はりぼて風に言えば下じきかな?)があり、そこにおのおのデータを書き込むことでひとつのドットの色を表現しているらしい

赤・緑・青・輝度 の4枚らしい。

で、たとえば、画面上で Xが5、Yが0という場所に点を一個打ちたいとする。

これが320x200x256やVESAの高解像度等、単純にVRAMのあるアドレスに値を書けば反映される。

・VRAMは0xa0000から始まる
・X(横)が5、Y(縦)は0だから、単純に0xa0000から6番目、0xa0004番地。
・ここに0x8(色番号)とか書きこめばそこにドットが書かれる

しかしVGAの場合は1ドット=1ビットとなる。なので、同じように点を書くとすると・・・ (ちょっと色などはおいて置く)

・VRAMは0xa000から始まる
・X(横)が5、Y(縦)は0だから、単純に0xa0000から6番目、0xa0005番地ではない!
・左から6個目に点なので、0x40 (0000100000000000)。
・この値を0xa0000に書くと点が書かれる

こういう方式になるようだ。

当然これだけじゃ、0と1なので、白・黒など二色しか色は表現できない。

そこで他のプレーン?にも書き込みを行い、それらを重ね合わせた結果、赤なり緑なりの 色が表現される・・・・のかな????

1番プレーン〜4番プレーン(仮称)におのおのデータを書くらしいのはわかった。 では、具体的に2番プレーンに書き込むにはどうしたらいいのだろう???

最初、1番プレーンは0xa0000〜0xaFFFF、2番プレーンは0xb0000〜0xbffffとかいう感じではないかと思っていたが、どうも違うらしい。

AT互換機のVGAのプレーンは、どうも全て同じ番地のようだ!!!!????

・・・っということは、多分、書き込む前になにかしら命令を出して、プレーンを切り替えるというような作業が必要なんじゃないかな???

むずかしくてキツいが、OS-Wikiの該当ベージをことあるごとに読み込んでいます・・・

ラッチかぁ・・・どうもこれがカギみたいだなぁ・・・

Page Top

臭う・・・臭うぞ!? anchor.png

クサイのはこれである。シーケンサーという部分の

[0x02] Map Mask (プレーンごとの書き込み許可)

という所。ここはどうも、各プレーンへの書き込みを許認可しているようだ。そんなわけで、こういうことをしてみるとプレーン0〜3まで書き込めないか??

	//マップマスクの実験
	io_out8(0x03c4, 0x0002);   //00000000   
	for ( i = 0; i <= 512*1; i=i++)
	  {
	    p[i] = 0x6;
	  }

	io_out8(0x03c4, 0x0102);   //00000001   
	for ( i = 0; i <= 512*1; i=i++)
	  {
	    p[i] = 0x6;
	  } 

	io_out8(0x03c4, 0x0202);   //00000010   
	for ( i = 0; i <= 512*1; i=i++)
	  {
	    p[i] = 0x6;
	  }

	io_out8(0x03c4, 0x0302);   //00000011
	for ( i = 0; i <= 512*1; i=i++)
	  {
	    p[i] = 0x6;
	  }

うーーーん・・・なにも変化がない・・・

Page Top

ズギャ!!! 色が出たぞ!!!!! anchor.png

・・・・なっあぁるほどおぉぉぉお!!!!!!! そういうことなのね!!!

オイラが今までなにやっても変化がなかったコードがこれ。

	io_out8(0x03ce, 0x0005);  //書き込みモードを0に
	io_out8(0x03ce, 0x0301);  //全プレーンをenableに
	io_out8(0x03ce, 0x0700);  //色番号7をセット
	io_out8(0x03ce, 0xff08);  //描画データのマスク

	for ( i = 0; i <= 512*2; i++){
	p[i] = 0x6;
	}
q0.jpg

値をいろいろ変化させても白い色の点しか書けない。なにか致命的なミスや勘違いでもあるのかと、かなり迷宮のラビリンスですた・・・

解決!! っというか、問題点が見つかった。

なんのことはない! はりぼてのio_out8は伊達にに字が付いていない。これは8バイトしかアクセスしないんじゃねーかよ!!!  ・・・・orz・・・

見たほうが早いよね? 同じ目的のコードだけど、これで解決!!

	io_out8(0x03ce, 0x05);  //書き込みモードを0に
	io_out8(0x03cf, 0x00); 

	io_out8(0x03ce, 0x01);  //全プレーンをenableに
	io_out8(0x03cf, 0x03);  

	io_out8(0x03ce, 0x00);  //色番号7をセット
	io_out8(0x03cf, 0x07);  

	io_out8(0x03ce, 0x08);  //描画データのマスク
	io_out8(0x03cf, 0xff);  

	for ( i = 0; i <= 512*2; i++){
	p[i] = 0x6;
	}
q1.jpg

うーーーん・・・。今思えばかなりマヌケな話だなぁ我ながら・・・(^^; まあ、とにもかくにも変化が起こり、レジスタにちょっかいを出すと効果が出るというところまで漕ぎ着けた。後はさっそく、各プレーンの意味等を実験してみよう!!

・・・ラッチは?・・・・ラ・・・ラッチはあぁぁぁぁ????・・・・

Page Top

まずはモード3に絞ってみるか・・・ anchor.png

OS-Wikiによると、もっとも有用なモードとある。(OSASKでも多様されているらしい)

とりあえずこのモードに絞っていろいろ試してみよう。

  • まずはEnable Set/Resetについて。
    • プレーン0のみ・プレーン1のみ・・・・プレーン2と3のみ・・・等等と実験してみたが変化はない・・・ って!!!! これはモード0のみしか効かないのか・・・(最初によく読もう)
  • 次はBit Mask (描画マスク)ね
    • これはまあわかるね。読んで字のごとくだし・・・(^^
  • 次にSet/Reset (ラッチとの演算に関するレジスタ)。
    • ここに色をセットするとその通りの色が書き込まれる・・・でいいのかな??
    • ここは頭4ビットが無視されるんだから事実上0x0〜0xFまでの値しか指定できない。つまり、16色つーことかな。
      • 0x00:
      • 0x01:暗い青
      • 0x02:暗い緑
      • 0x03:暗い水色
      • 0x04:暗い赤
      • 0x05:暗い紫
      • 0x06:暗い黄色
      • 0x07:暗い灰色
      • 0x08:さらに暗い灰色
      • 0x09:
      • 0x0a:
      • 0x0b:水色
      • 0x0c:
      • 0x0d:
      • 0x0e:黄色
      • 0x01:
Page Top

そんなにややこしくない・・・のかな?? anchor.png

うーーーーーん・・・・

ここまでやってみたけど、少なくともモード3なら、そんなにバカみたいにややこしいわけではないのかなぁ・・・

ちょっと試しに、harib01g で同じ動作をするbox関数を作ってみるか・・・

Page Top

試作boxfill8関数でけたー! anchor.png

おっしゃぁ! 出来た! これでどうじゃろ!???

void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{
 int i,i2,i3;
 int xx0,xx1;
 unsigned char maskx;

 io_out8(0x03ce, 0x00);io_out8(0x03cf, c);    //色番号をセット

 //x(横)の始点と終点を8で丸める
 if ( x0 % 8 == 0 )
   {
     xx0 = x0;
   }
 else
   {
     xx0 = x0 - ( x0 % 8);
   }

 if ( x1 % 8 == 0 )
   {
     xx1 = x1;
   }
 else
   {
     xx1 = x1 + ( x1 % 8) - 8;
   }

 for ( i = y0; i <= y1; i++)
   {
     for ( i2 = xx0; i2 <= xx1; i2=i2+8)
	{
	  //xの先頭部分との修正
	  if (i2 == xx0)
	    {
		  maskx = 0xFF;
		  maskx = maskx >> (x0 % 8 );

		  io_out8(0x03ce, 0x08);  //描画データのマスク
		  io_out8(0x03cf, maskx);  //描画データのマスク
	    }
	  //xのお尻の部分の修正
	  if ( i2 == xx1 )
	    {
	      maskx = 0xFF;
	      maskx = maskx << (8 - (x1 % 8));

	      io_out8(0x03ce, 0x08);  //描画データのマスク
	      io_out8(0x03cf, maskx);  //描画データのマスク
	    }

	  //頭でもお尻でもなければ・・・
	  if ( i2 != xx0 && i2 != xx1 )
	    {
		  io_out8(0x03ce, 0x08);  //描画データのマスク
		  io_out8(0x03cf, 0xff);  //マスクなし
	    }

	  vram[ ( i * xsize / 8 ) + (i2 / 8) ] = 0xff;

	}

   }

 	return;
}
Page Top

あれえぇ??? anchor.png

まってまって!?

マスクって、覆ったところ(0の部分)って、元の色じゃなくて新たに黒で塗られちゃうの!??? えーーーーーー!!! ダメじゃん!!!

Page Top

俺はハンパでナンパな男なんだよ! (ヴオォォォォ!!) anchor.png

うーーん。8の倍数でないx座標だとどうしてもこうなってしまう・・・

q2.jpg

もともとある色を崩さずに書き込む方法ってないのかなぁ・・・ (OSASKのフォント描写の方法がヒントのようだがいまだにラッチがなんなのかよくわからない・・・)

「ラッチに背景色を読み込んでおいて・・・」とある。

このラッチという場所に色のデータを読み込ませる・・・(この場合は背景の緑色)

ラッチに色を読み込ませるにはリードすればいい???

え? じゃ、たとえば、 aaa = 0xa0001; とか、そういう意味????

・・・やっぱ違うよなぁ・・・・

	  io_out8(0x03ce, 0x08);  //描画データのマスク
	  io_out8(0x03cf, 0xff);  //マスクなし

	  //psetmodeに・・・
	  io_out8(0x03ce, 0x03);  
	  io_out8(0x03cf, 0x00);  

	  tmp = vram[( i * xsize / 8 ) + (i2 / 8) ] ;  //読み込んでラッチに・・・?
	  vram[ ( i * xsize / 8 ) + (i2 / 8) ] = maskx;
Page Top

あっれぇ? ちょっとまてよ!?? anchor.png

・・・こゆことか!? こーゆーこーとーかーーーーぁ!!

Page Top

わかったあぁぁぁぁ!!!!!!!!!!! anchor.png


Attach file: fileq2.jpg 56DL [Info] fileq1.jpg 45DL [Info] fileq0.jpg 45DL [Info]

Last-modified: 2012-10-22 (Mon) 22:05:11 (GMT) (2818d) by