마이컴 1994년 1월호 - 프로그래머가 되는 길 

 C로 구현하는 DISKCOPY 

 

 

 

여러분이 컴퓨터를 처음 접했을때 가장 먼저 배우는 것들이 FORMAT이나 DISKCOPY 등과 같은 디스크에 관한 도스 명령어일 것이다. 왜냐하면 컴퓨터를 사용하는데 있어서 모든 것이 디스크로부터 시작하기 때문이다.

 

그래서 디스크를 제어하는 프로그램을 만들어 보는 것도 컴퓨터를 이해하는데 도움이 될 것이다. 그럼 C에서는 어떻게 디스크를 관리하는지 알아보고 간단한 DISKCOPY 프로그램을 작성해 보자.

 

 

 

도스 외부명령에서 지원하는 DISKCOPY의 모습

 


C에는 디스크를 관리하는 함수가 하나 존재한다. 그것이 바로 biosdisk() 라는 함수이다. 이 biosdisk() 라는 함수는 바이오스 인터럽트 0x13번을 직접 호출하여 바이오스의 디스크 기능들을 사용하게 된다. 함수 원형은 아래와 같다.

 

 

 

biosdisk() 함수 원형

#include <bios.h>
int biosdisk(int cmd, int drive, int head, int track, int sector, int nsects, void *buffer);

 

각각의 파라미터에 대해 살펴보면 drive는 어느 디스크 드라이브가 사용되는지에 관한 것이고, head, track, sector는 그 디스크의 특정값이다. 또 nsects는 읽거나 쓸 섹터의 개수를 나타낸다. 그리고 마지막으로 cmd는 이 함수가 수행될 기능을 나타낸다. 자주 사용되는 기능을 살펴 보면 다음과 같다.

 

0 :디스크 시스템을 초기화 한다.
1 : 최근 사용된 디스크 기능 상태 리턴
2 : 섹터 읽기
3 : 섹터 쓰기
4 : 섹터 확인
5 : 디스크 포맷
8 : 디스크의 정보를 얻는다.
10 : 드라이브 준비상태 검사


그외에도 배드섹터(Bad Sector) 를 표시하거나 여러 가지 기능이 존재한다. 더 자세히 알고 싶다면 바이오스 인터럽트 0x13번을 참조하면 될 것이다. 그리고 biosdisk() 함수는 파일 레벨하에서 섹터들 자체에 대한 기능을 수행하므로 파일의 내용이나 디렉토리 내용을 파괴할 수도 있으므로 주의가 필요하다.


이러한 biosdisk()를 이용하여 간단한 DISKCOPY 프로그램을 작성 하였다. 이 프로그램의 원리는 원시 디스크에서 '트랙수 x 헤드수' 만큼을 읽어 임시 파일 'c:\simcopy.$$$'라는 파일에 복사를 한 후에 다시 그 파일을 디스크에 저장하는 형식을 취 하였다.


이러한 방법의 장점은 한번에 읽기/쓰기가 가능하고 여러장 복사가 가능하다. 반면에 하드드라이브에 디스크 용량 만큼의 사용 가능한 공간이 필요하다. 그리고 대상 디스크는 포맷이 되었다고 가정했다.


약간의 변형을 가해 보다좋은 프로그램이 되도록 만들어 보자.

 

 

 

C로 구현한 diskcopy 함수의 변형된 Simcopy.c 소스

// Simcpy.C 

// using BORLAND C++ 3.1


#include <stdio.h>         // printf
#include <io.h>              // creat, close, open, Iseek
#include <sys/stat.h>    // S_IREAD | S_IWRITE
#include <fcntl.h>          // O_BINARY | O_RDWR 
#include <conio.h>        // getch(); 
#include <bios.h>          // biosdisk();


typedef enum (dt360=0, dt1200, dt720, dt1440) DISKTYPE :
struct {
        int heads:
        int tracks:
        int sectors;
} disk[4]={ { 2, 40, 9 },    // 360KB CA
                 { 2, 80, 15},   // 1.2MB 디스켓
                 { 2, 80, 9 },    // 720KB C
                 { 2, 80, 18 }   // 1.44MB 디스켓

}; 

 


// Drive   'A:'=0, 'B:'=1
void DiskCopy( int Drive, DISKTYPE type )

{
    char Buffer[ 185*12 ];                 // max size;
    int i, j;
    int handle                                   // file handle
    char path[]="c:\\simcpy.$$$":     // 임시 파일명


    printf( "\n%c 에 원본디스켓을 넣으세요: ", Drive+'A'):

    getch() ;


    if ((handle = creat( path, S_IREAD | S_IWRITE))== -1)

        return;     // 새로운 파일을 만든다. 만약 실패하면 종료.
    close (handle):


    if ((handle open( path, O_BINARY | O_RDWR, S_IREAD | S_IWRITE)) == -1)

         return;     // 존재하는 파일을 연다. 실패하면 종료.


// 트랙수 x 헤드수 만큼을 읽어서 파일에 저장한다.
    for ( i=0; i<disk[type].tracks; i++ ) {

        for ( j=0; j<disk[type].heads; j++) {

            biosdisk ( 2, Drive, j, i, 1, 15, Buffer);
            write ( handle, Buffer, disk [type].sectors * 512);

        }
    }


    printf( "\n%c 드라이브에 대상 디스켓을 넣으주십시오. \n", Drive+'A');
    getch();

    Iseek (handle, 0L, SEEK_SET);       // file pointer를 파일의 선두로


    // 파일로부터 디스크에 복사한다.
    for ( i=0; i<disk [type].tracks; i++ ) {
        for ( j=0; j<disk[type].heads; j++) {
            read ( handle, &Buffer, disk [type].sectors * 512 );
            biosdisk ( 3, Drive, j, i, 15, Buffer );

        }

    }  


    // 여러장 복사를 가능하게 하려면 복사하는 부분을 루프를 돌려주면 된다.
    close (handle);  // open한 파일의 핸들을 닫는다.
    unlink(path);     // 임시 파일을 지운다.
}

 


void main( )
{
    // 여기서는 단순하게 A: 에서 1.2MB의 디스켓을  복사하는 것으로 만들었다.

    // 직접 인터페이스 부분을 만들어 보세요.
    DiskCopy(0, dt1200) :
 }

 

 

 

 

 

 

 

  이글은 지금은 없어진 컴퓨터 잡지, 마이컴 1994년 1월호 기사에서 발췌한 내용입니다

 

글이 마음에 드시면 아래 공감버튼 살짝 눌러주세요.

공감과 댓글은 저에게 큰 힘이 됩니다. 

 

 

 

 

 

728x90
반응형
Posted by 전화카드
,