마이컴 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월호 기사에서 발췌한 내용입니다 |
글이 마음에 드시면 아래 공감♡버튼 살짝 눌러주세요.
공감과 댓글은 저에게 큰 힘이 됩니다.
'컴퓨터관련 > 마이컴 1994년 1월호' 카테고리의 다른 글
마이컴 1994년 1월호 - 게임분석, 미리내 소프트웨어의 아파차차 (1) | 2023.09.05 |
---|---|
마이컴 1994년 1월호 - 게임 시장을 잡아라 12, 사업가의 핏줄을 물려받은「써텍」 (0) | 2023.09.01 |
마이컴 1994년 1월호 - 이달의 게임 Best 10과 신작게임 소식 (2) | 2023.08.30 |
마이컴 1994년 1월호 - 도스 길잡이 7, ANSI.SYS의 넉넉한 기능들(2) (0) | 2023.07.27 |
마이컴 1994년 1월호 - 하드웨어 분석, 옥소리 멀티미디어 키트 (0) | 2023.07.21 |
마이컴 1994년 1월호 - 데이지휠에서 잉크젯까지, 프린터 20년 역사 (0) | 2023.07.15 |
마이컴 1994년 1월호 - 특집기획, PCI 버스, 베사를 언제쯤 추월할까 (0) | 2023.07.11 |
마이컴 1994년 1월호 - 공개 소프트웨어 분석 (0) | 2023.07.05 |