📄 mkrom.c
字号:
/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright Peter Van Oudenaren , 1993
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/*
*****************************************************************************
MKROM.C - Create a rom disk from an MS-DOS sudirectory
Summary
MKROM subdir
Description
Traverses the subdirectory "subdir" and make an exact image of that
subdirectory in a file named romdisk.dat. The file romdisk.dat
can be placed directly into a rom and accessed via the rom disk
device driver.
Example:
mkrom c:\dev\romimage
*****************************************************************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <conio.h>
#include <dos.h>
#include <io.h>
#include <direct.h>
#include <string.h>
#include <pcdisk.h>
/* Write your own routines to create these. */
#define BIN_VOL_LABEL 0x12345678L
#define STR_VOL_LABEL "VOLUMELABE" /* 11 chars max */
#define SUPPORT_WIN95 1 /* leave this on if building in win95/nt. off in dos */
#if (SUPPORT_WIN95)
typedef struct _finddata_t statobj_t;
#else
typedef struct _find_t statobj_t;
#endif
#ifndef MAX_PATH_LEN
#if (SUPPORT_WIN95)
#define MAX_PATH_LEN 260
#else
#define MAX_PATH_LEN 256
#endif
#endif
word host_disk_size;
int traverse(char *name, int level);
int copy_files(char *name, int level);
int make_directories(char *name, int level);
void usage() /*__fn__*/
{
printf("Usage: mkrom path [extra_blocks]\n");
}
void bintoc(void);
void exit(int);
char imagepath[MAX_PATH_LEN];
int n_files = 0;
int n_subs = 0;
long n_dir_clusters = 2; // Always start with a few extra
long n_file_clusters = 0;
int cluster_size = 1;
int cluster_size_bytes = 512;
int fat_size = 2; /* bytes per fat entry */
int root_path_len = 0; /* remember how much of each path is the root */
int bytes_to_clusters(long bytes);
int bytes_to_blocks(long bytes);
int blocks_to_clusters(long blocks);
int dirents_to_clusters(int dirents);
int bytes_to_clusters(long bytes)
{
long l;
l = blocks_to_clusters(bytes_to_blocks(bytes));
return (l);
}
int bytes_to_blocks(long bytes)
{
long l;
l = ((bytes+511)/512);
return l;
}
int blocks_to_clusters(long blocks)
{
long l;
l = ((blocks + cluster_size - 1) / cluster_size);
return l;
}
int dirents_to_clusters(int dirents)
{
return (blocks_to_clusters((dirents + 15)/16));
}
BOOLEAN hostdisk_io(word driveno, dword block, void KS_FAR *buffer, word count, BOOLEAN reading);
int hostdiskformat(void) /*__fn__*/
{
DDRIVE *pdr;
int driveno;
DEV_GEOMETRY geometry;
driveno = 0;
pdr = pc_drno_to_drive_struct(0);
if (!pdr || !(pdr->drive_flags&DRIVE_FLAGS_VALID) )
{
printf("No valid drive A: present\n");
return -1;
}
if (pdr->dev_table_drive_io != hostdisk_io)
{
printf("Drive A: is not a host disk. rebuild\n");
return -1;
}
if (!check_media(driveno, FALSE, TRUE, FALSE))
if (!check_media(driveno, FALSE, TRUE, FALSE))
{
printf("Check media failed.\n");
return(-1);
}
/* This must be called before calling the later routines */
if (!pc_get_media_parms("A:", &geometry))
{
printf("Drive A: get media failedisk. rebuild\n");
return(-1);
}
/* Call the low level media format. Don't do this if formatting a
volume that is the second partition on the drive */
printf("Calling media format\n");
if (!pc_format_media("A:", &geometry))
{
printf("Media format failed\n");
return(-1);
}
/* Put the DOS format */
if (!pc_format_volume("A:", &geometry))
{
printf("Format volume failed\n");
return(-1);
}
return (0);
}
void main(int argc, char **argv) /*__fn__*/
{
long n_fat_entries;
long n_fat_clusters;
long n_clusters;
int extra_blocks;
/* past 0 */
argc--;
argv++;
if (!argc)
{
usage();
exit(0);
}
else /* Get the path */
pc_str2upper(&imagepath[0],*argv); /* copy and to upper */
argc--;
argv++;
if (argc)
extra_blocks = atoi(*argv);
else
extra_blocks = 0;
printf("Extra blocks == %d\n", extra_blocks);
/* How long is the path to the root.. We'll strip this off of the
front of the strings when we build RTFS files in the file immage */
root_path_len = tc_strlen(imagepath);
/* Initialize ertfs */
if (!pc_ertfs_init())
{
printf("pc_ertfs_init failed\n");
return;
}
traverse(imagepath, 0);
printf("\n");
printf("\n");
printf("\n");
printf("%10.10d Files\n", n_files);
printf("%10.10d Subdirectories\n", n_subs);
printf("%10.10ld Directory clusters\n", n_dir_clusters);
printf("%10.10ld Bytes in file\n", n_file_clusters * cluster_size_bytes);
printf("\n");
printf("\n");
n_file_clusters = n_file_clusters + extra_blocks/cluster_size;
n_fat_entries = 256 + n_dir_clusters + n_file_clusters;
printf("%ld NFAT entries, byte %ld\n", n_fat_entries, (n_fat_entries * fat_size));
n_fat_clusters = 2 * bytes_to_clusters(n_fat_entries * fat_size);
n_clusters = n_dir_clusters + n_file_clusters + n_fat_clusters;
// Was this ? BUG (n_fat_clusters * cluster_size_bytes + fat_size*2-1)/fat_size;
printf("%10.10ld n_dir_clusters\n", n_dir_clusters);
printf("%10.10ld n_file_clusters\n", n_file_clusters);
printf("%10.10ld n_fat_clusters\n", n_fat_clusters);
printf("%10.10ld n_clusters\n", n_clusters);
host_disk_size = (word) (n_clusters * cluster_size);
/* host disk uses host_disk_size in format media */
printf("Total blocks required = %d\n",host_disk_size);
if (hostdiskformat() != 0)
{
printf("Format failed \n");
exit(-1);
}
pc_set_default_drive("A:");
printf("Creating subdirectories\n");
if (make_directories(imagepath, 0) < 0)
{
printf("Can't create subdirectories \n");
exit(-1);
}
printf("Copying files\n");
if (copy_files(imagepath, 0) < 0)
{
printf("Can't copy files\n");
printf("Try adding extra blocks to the comand line\n");
printf("Increment extra blocks untill it works\n");
printf("For example: mkrom \\romdata 4\n");
exit(-1);
}
printf("Creating romdisk.h from filedisk.dat\n");
bintoc();
}
int traverse(char *name, int level)
{
statobj_t statobj;
char path[MAX_PATH_LEN];
char *pkind;
int entries;
int i;
#if (SUPPORT_WIN95)
long dd;
#endif
entries = 0;
for (i = 0; i < level; i++)
printf(" ");
printf("Processing directory %s\n", name);
strcpy(path, name);
strcat(path, "\\*.*");
/* Print them all */
#if (SUPPORT_WIN95)
if ((dd = _findfirst(path, &statobj)) < 0)
#else
if (_dos_findfirst(path, _A_NORMAL|_A_SUBDIR, &statobj)!=0)
#endif
{
return(0);
}
else
{
do
{
entries += 1;
#if (VFAT)
entries += (tc_strlen(statobj.name) + 12)/13; // Account for lfn data
#endif
if ( (strcmp(".", statobj.name)==0) ||
(strcmp("..", statobj.name)==0) )
pkind = "d";
else if( statobj.attrib & _A_SUBDIR )
{
n_subs += 1;
pkind = "d";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -