비디오 메모리 직접 제어해보신 분~
글쓴이: kkojiband / 작성시간: 화, 2003/07/01 - 10:19오후
0x12 mode 가 16color 640x480 라고 하길래 그 mode 로 이것저것 해보려고 작업 중인데요...
A0000h를 시작 주소로 pixel 당 4bit 씩 할당되는걸로 알고 있는데, 제가 넣어보니까 흑백 칼라더라구요 pixel 당 1bit...
책이 잘못된 건가요??
그래서 지금은 0x13 mode 를 사용하고 있는데 해상도가 너무 낮아요...
640x480 에 16color 이상의 mode 는 없는건가요?
그리고 bios 에서 기본적으로 제공하는 mode 외에 video card 에 있는 bios 에서 지원하는 mode 들도 그냥 똑같은 방식으로 사용할수있는건가요?
관련자료가 하도 없어서 원서 사다놓고 보고 있는데...한계가 있군요...--;
아시는 분 좀 도와주세요~
Forums:
Re: 비디오 메모리 직접 제어해보신 분~
선형 프레임버퍼 모드에서는 16색이면 2의 4승해서 4비트 할당되는 것이 맞습니다. 그렇지만 표준 VGA 모드라면 다릅니다. 8086/88 프로세서의 세그먼트 크기 제한때문에 64kB 플레인 4개를 중첩해서 256KB 메모리를 구성하는 독특한 방법을 쓰거든요.
요즘 VGA 카드들은 비디오 모드를 초기화할 때 BIOS 인터럽트를 안쓰고 하드웨어 레지스터를 직접 조작하는 방법을 사용합니다. 이 방법은 그래픽 카드마다, 제조사마다 판이하게 다릅니다. 자세한 그래픽 카드 프로그래밍 방법을 알고 싶으시다면 ATI나 nVIDIA같은 회사에 직접 요청을 하셔서 입수한 정보를 외부에 발설하지 않겠다고 약정을 한 뒤 매뉴얼을 받아서 그걸 보고 개발을 하시면 됩니다.
Re: 비디오 메모리 직접 제어해보신 분~
플래인이 4개이고 각 플레인당 1비트씩입니다.
플레인 선택하는거 예제로 있을겁니다.
잘 보시면 플레인별로 1비트씩 래치시키는거 볼수 있습니다. 예제들 대부분...
추가.
그리고 BIOS에서 제공하는 것 외에 VESA BIOS를 지원한다면 리얼모드에서는
보통 약 1024x768까지정도 지원가능합니다. C800:0000이던가? 확실치는 않는데 VESA초기화 루틴이 들어 있는게 그 근처일겁니다.
그 외의 방식으로는 여러가지 많고...
그것은 표준화하기 어려운 문제로 그래픽칩마다 조금씩 다른 방법을 갖습니다.
저는 개인적으로 리눅스에서 페이징을 지원했으면 좋겠는데....
(( 여기서 말하는 페이징이란 고속 복사해서 화면을 교체하는 것이 아니고
시작 주소만 바뀌면서 화면이 전환되는 페이징을 원합니다. ))
그것을 보통 가속기능의 일종이라고 하는 사람이 있을런지 모르나
전 아니라고 봅니다. 아무튼 어려운 문제네요.
다시 본점으로 돌아와서
이왕이면 16비트부분은 건너뛰고 256색모드부터 해보시는것을 추천합니다.
256색 모드가 BIOS모드로는 0x13입니다. 320x240.
만약 13h모드라면 다음과 같이 하면 점이 찍힐겁니다.
*(((unsigned char *)0xa0000000L) + (y * 320) + x) = color;
암튼 어떤분은 DOS로 해볼것이 뭐가있냐고 하실지 모르겠는데....
전 DOS를 접해보는게 좋다는 주장한번 해봅니다.
지금 보면 대부분 운영체제의 울타리에 감싸져 밖을 못보고
그 안이 좋다고 밖에 나가지 말라고 하는 것같아서 예기해봅니다.
참고로 16비트는 위의 공식에서 플레인에 따른 4의 나머지를 취해서
하는 기억이 좀 남아있는데 제가 확실한 코드 재현할 정도의 기억력은
아니군요.
Re: 비디오 메모리 직접 제어해보신 분~
순수히 비디오 카드 제어법 (및 기타 하드웨어 제어 관련 지식)을
익히기 위한 게 목적이시라면, 특정한 비디오 카드를 놓고
거기에 맞는 자료를 찾아 프로그래밍 해 보시면 될 것 같습니다.
그게 아니고, 도형 등을 그리는 여러 루틴이 여러 하드웨어에
호환성있게 작동하길 원하는 것이라면, 구현 방향은 좀 달라지겠죠.
이 때는 VESA가 도움이 될 거라 생각됩니다.
16 컬러 같은 plane 을 사용하는 모드는 비교적 제어하기
까다롭습니다.속도도 잘 안나구요. 256 색상 이상 되면 plane 개념이
없기 때문에 ( 1 plane 만 씁니다.), bank selection 정도만 고려해주면
대체로 작동하게 돼 있구요. VESA 버젼이 높으면 선형 메모리로
쉽게 접근할 수도 있습니다.
이미 작성된 라이브러리를 이용하는 게 좋을 수도 있는데, djgpp에서는
알레그로 라이브러리가 있습니다. 그 소스로부터 배울 수도 있구요.
Orion Project : http://orionids.org
Re: 비디오 메모리 직접 제어해보신 분~
비디오모드 0x12이면 VGA 640x480x16이군요..
이 모드는 비디오 메모리가 아주 특이한 방식으로 구성되어 있습니다.
제가 이거 해 봤는데 몇가지 방법이 있습니다. 물론 절차는 상당히 복잡합니다.
어셈블리쓴다면 반드시 out 명령으로 VGA카드 레지스터에 직접 접근해야 합니다.
가장 쉬운거는 일명 Packed Pixel이라고 하는 쓰기 모드 2인데,
이것은 먼저 VGA 모드 레지스터의 쓰기 모드를 2로 세팅합니다.
그다음 픽셀로부터 메모리 주소를 계산하는데, 아래와 같이 계산합니다.
(x,y)접근시
접근 메모리 주소 = y*80 + x/8
(메모리주소는 세그먼트 0xa000 상대 오프셋 값입니다)
여기서 계산한 주소에는 (x,y)점이 포함된 8개의 점이 들어갑니다.
이때 바로 비디오메모리에 접근하게 되면, (x,y)가 포함된 근방의 점
8개가 동시에 같은 색이 되버리죠..
이 8개 중 하나를 선택하도록 제어하는것은 VGA레지스터 중
비트마스크 레지스터입니다.
비트마스크의 8개 비트는 (x,y)가 포함된 점 8개의 각 비트와 1대 1로
대응되고, 여기서 1이 된 부분은 비디오메모리에 입력된 색이 그대로
나갑니다.
이 비트마스크는 아래와 같은 방법으로 계산하면 됩니다.
출력 비트마스크 = 0x80 >> ( x % 8 )
비트마스크를 계산했으면 먼저 비트마스크를 세팅한 다음.
아까 앞에서 계산한 주소의 비디오메모리에서 임의의 레지스터로 읽기를 시도하고,
그다음 VGA비디오메모리에 쓰기를 해야 합니다.
VGA메모리 접근할때 왜 읽기를 먼저 수행하냐면,
VGA 래치 레지스터를 갱신해야 하기 때문입니다.
이거 안하면 엉뚱한데 써질 수도 있지요.
실제 VGA 라이브러리들은 이 640x480x16모드에서 비디오 메모리 접근시
반드시 읽기를 수행한다음 쓰기를 하도록 되어 있습니다.
이렇게 해서 점 하나 출력하는 거고요.
이 Packed Pixel 이외에도 Mode 0 Plane Write, Mode 0 Set/Reset 방식을
이용해서 하는 출력방법이 몇가지 더 있습니다.
그리고 VGA레지스터는
비트마스크 레지스터의 경우 0x3ce index 8입니다.
(먼저 out명령으로 포트 0x3ce에 8을 보낸 다음에 0x3cf에 쓰기 시도시
비트마스크로 들어가고, 반대로 읽기 시도시는 비트마스크값이 나옵니다)
모드 레지스터는 0x3ce index 6입니다.
그외에도 http://www.wotsit.org 등에서 VGA로 검색해보면
문서 구할 수 있는데, 여기서는 기타 다른 레지스터 내용도 볼수
있고요 (이해 정말 안갈겁니다)
이거 이유에 대해서 자세한 내용을 말한다면 너무 길어지므로 이만 줄이고요.
자세한 내용은 'C로 하드웨어 주무르기'에 나와 있습니다.
상당히 오래된 책인데(Turbo C 사용) 지금은 절판됐는지 모르겠습니다.
여기서 VGA부분을 보면 님도 정말 이해 안갈겁니다. 그만큼 복잡하거든요.
Written By the Black Knight of Destruction
댓글 달기