J-한솔넷

DOS 6.2에서 Turbo C 를 이용하여 비디오 메모리를 직접 엑세스하여 화면 표시하기 본문

프로그래밍/C

DOS 6.2에서 Turbo C 를 이용하여 비디오 메모리를 직접 엑세스하여 화면 표시하기

jhansol 2014. 4. 11. 15:34

오랜만에 도스기반의 C프로그램을 해봅니다.^^

감회가 새롭군요...^^


이 프로그램은 한글 MS DOS 6.2를 VMWare 7에 설치하고 Turbo C 2.01을 설치하여 프로그램한 것입니다.

이 프로그램은 텍스트 화면을 기반으로 한 프로그램의 첫 화면을 출력하는 프로그램입니다. C언어의 표준함수를 이용하지 않고 비디오메모리에 직접 내용을 기록하여 화면을 표시하는 방식입니다.

과거에는 많이 쓰왔던 방식이지만 윈도우 환경으로 전환되면서 역사속으로 퇴장한 방법입니다. 그렇지만 오랜만에 해보니 감해가 새롭고 왠지 교향온 기분입니다.


이 프로그램을 살펴보기 전 몇가지 기본 지식을 알고 있는 것이 좋을 듯 하여 몇자 적어봅니다.


비디오 메모리

모니터 화면에 표시할 내용이 저장되어 있는 메모리로 기기 및 운영제제에 따라 그 위치(번지)가 예약되어 있습니다.

도스 환경에서 위치는 0xB8000000 번지에 있습니다.


표시 화면의 크기

도스 환경에서 모니터에 표시되는 내용은 총 25줄 80칸으로 구성되어 있습니다. 그러니까 화면에 표시할 수 있는 총 문자수는 아래와 같이 2000자가 되는군요^^


25 * 80 = 2000



화면 표시 내용

모니터에 표시될 내용은 비디오 메모리에 아래와 같은 형태로 저장되어 있습니다.


문자

(1바이트)

속성

(1바이트)

 문자

 속성

 문자

 속성

 ....


위의 표와 같이 화면에 한 문자를 표시하기 위해서는 2바이트가 필요합니다. 그러면 화면에 내용을 꽉 채우기 위해서는 총 4000바이트가 필요하네요.


화면에 표시할 문자와의 관

내가 원하는 위치에 문자를 표시하려면 비디오 메모리의 몇번째 위치에 내용을 쓰면 될까요?


메모리상의 위치 = ( 줄 번호 * 80 + 칸번호 ) * 2


문자와 속성을 하나의 구조체로 표시하고 비디오 메모리에 쓰도록하면 위치 계산이 더욱 간편해집니다.


메모리상의 위치 = 줄 번호 * 80 + 칸번호 * 2


프로그램 실행 결과

아래 소스를 컴파일하고 실행했을 때 이런 화면이 출력됩니다.




프로그램 소스


#include

#include void putStrToVram( char *str, int line, int col, unsigned int forground, unsigned int background ); void fillRectToVram( char ch, int start_line, int start_col, int end_line, int end_col, unsigned int forground, unsigned int background ); void drawBox( int start_line, int start_col, int end_line, int end_col, unsigned int forground, unsigned int background ); /* 텍스트 화면에 표시되는 문자의 전경색과 배경색을 나타내는 속성을 표시하기 위한 구조체 하위 4비트는 전경색을 상위 4비트는 배경색을 나타냄 */ struct char_attr { unsigned int forg : 4; unsigned int back : 4; }; /* 텍스트 화면에 문자를 표시하기 위한 구조체 비디오 메모리에 표시되는 내용은 문자와 문자를 어떤 색으로 표시할 지 지정하는 속성으로 구성됨 비디메모리에 아래와 같은 형태로 화면 표시 내용이 저장됨 |문자|속성|문자|속성|문자|속성| */ struct video_char { unsigned char ch; struct char_attr attr; } /* 화면을 그리는 매인 함수 */ main() { fillRectToVram( ' ', 0, 0, 0, 79, BLACK, WHITE ); fillRectToVram( ' ', 1, 0, 23, 79, BLACK, LIGHTGRAY ); fillRectToVram( ' ', 24, 0, 24, 79, BLACK, WHITE ); putStrToVram( "한솔 툴킷", 0, 2, BLACK, WHITE ); putStrToVram( "Version 1.0", 0, 67, RED, WHITE ); putStrToVram( "현재 대기중...", 24, 2, BLUE, WHITE ); fillRectToVram( ' ', 8, 16, 14, 65, WHITE, BLUE ); drawBox( 8, 17, 14, 64, WHITE, BLUE ); putStrToVram( "Hansol Toolkit (한솔 툴킷)", 9, 27, YELLOW, BLUE ); putStrToVram( "Ver 1.0", 10, 36, RED, BLUE ); putStrToVram( "(C) Copyright 2014 by JHansol", 12, 26, WHITE, BLUE ); putStrToVram( "이 풀그림은 얼마든지 배포 가능합니다.", 13, 22, WHITE, BLUE ); } /* 비디오 메모리에 문자를 직접 쓰는 함수 */ void putStrToVram( char *str, int line, int col, unsigned int forground, unsigned int background ) { struct video_char far *vram = (struct video_char far *)0xB8000000; int pos; struct video_char vch; pos = line * 80 + col; while( *str != NULL ) { vch.ch = *str++; vch.attr.forg = forground; vch.attr.back = background; *(vram + pos++) = vch; } } /* 비디오 메모리에 사각형 모양으로 문자를 채우는 함수 */ void fillRectToVram( char ch, int start_line, int start_col, int end_line, int end_col, unsigned int forground, unsigned int background ) { struct video_char far *vram = (struct video_char far *)0xB8000000; int pos, i, j; struct video_char vch; vch.ch = ch; vch.attr.back = background; vch.attr.forg = forground; for( i = start_line ; i <= end_line ; i++ ) { for( j = start_col ; j <= end_col ; j++ ) { pos = i * 80 + j; *(vram + pos) = vch; } } } /* 비디오 메모리에 직접 박스를 그리는 함수 */ void drawBox( int start_line, int start_col, int end_line, int end_col, unsigned int forground, unsigned int background ) { struct video_char far *vram = (struct video_char far *)0xB8000000; int pos, i, j; struct video_char vch; vch.ch = '-'; vch.attr.forg = forground; vch.attr.back = background; for( i = start_col ; i <= end_col ; i++ ) { pos = start_line * 80 + i; *(vram + pos) = vch; pos = end_line * 80 + i; *(vram + pos) = vch; } vch.ch = '|'; for( i = start_line + 1 ; i < end_line ; i++ ) { pos = i * 80 + start_col; *(vram + pos) = vch; pos = i * 80 + end_col; *(vram + pos) = vch; } }


'프로그래밍 > C' 카테고리의 다른 글

지가 미로를 탐색하는 프로그램입니다.  (1) 2014.04.18
리눅스에서 C 프로그램하기  (0) 2012.06.27