mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-10-12 05:24:02 +00:00
mkdos33fs: properly create catalog tables
this didn't work at all before
This commit is contained in:
parent
a868c4957b
commit
98a0c6b2b3
2
dos33fs-utils/TODO
Normal file
2
dos33fs-utils/TODO
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
getopt in dos33fs
|
||||||
|
BSAVE/BLOAD command in dos33fs, get rid of need for makeb
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "dos33.h"
|
#include "dos33.h"
|
||||||
|
|
||||||
|
static int debug=1;
|
||||||
|
|
||||||
static unsigned char sector_buffer[BYTES_PER_SECTOR];
|
static unsigned char sector_buffer[BYTES_PER_SECTOR];
|
||||||
|
|
||||||
static int ones_lookup[16]={
|
static int ones_lookup[16]={
|
||||||
@ -422,89 +424,98 @@ found_one:
|
|||||||
return ((found_track<<8)+found_sector);
|
return ((found_track<<8)+found_sector);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* creates file apple_filename on the image from local file filename */
|
#define ERROR_INVALID_FILENAME 1
|
||||||
/* returns ?? */
|
#define ERROR_FILE_NOT_FOUND 2
|
||||||
|
#define ERROR_NO_SPACE 3
|
||||||
|
#define ERROR_IMAGE_NOT_FOUND 4
|
||||||
|
#define ERROR_CATALOG_FULL 5
|
||||||
|
|
||||||
|
/* creates file apple_filename on the image from local file filename */
|
||||||
|
/* returns ?? */
|
||||||
static int dos33_add_file(int fd,char type,char *filename,
|
static int dos33_add_file(int fd,char type,char *filename,
|
||||||
char *apple_filename) {
|
char *apple_filename) {
|
||||||
|
|
||||||
int free_space,file_size,needed_sectors;
|
|
||||||
struct stat file_info;
|
|
||||||
int size_in_sectors=0;
|
|
||||||
int initial_ts_list=0,ts_list=0,i,data_ts,x,bytes_read=0,old_ts_list;
|
|
||||||
int catalog_track,catalog_sector,sectors_used=0;
|
|
||||||
int input_fd;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (apple_filename[0]<64) {
|
int free_space,file_size,needed_sectors;
|
||||||
fprintf(stderr,"Error! First char of filename must be ASCII 64 or above!\n");
|
struct stat file_info;
|
||||||
exit(3);
|
int size_in_sectors=0;
|
||||||
}
|
int initial_ts_list=0,ts_list=0,i,data_ts,x,bytes_read=0,old_ts_list;
|
||||||
{
|
int catalog_track,catalog_sector,sectors_used=0;
|
||||||
int i;
|
int input_fd;
|
||||||
|
int result;
|
||||||
for(i=0;i<strlen(apple_filename);i++) {
|
|
||||||
if (apple_filename[i]==',') {
|
|
||||||
fprintf(stderr,"Error! Cannot have , in a filename!\n");
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME */
|
|
||||||
/* check type */
|
|
||||||
/* and sanity check a/b filesize is set properly */
|
|
||||||
|
|
||||||
|
|
||||||
/* Determine size of file to upload */
|
|
||||||
if (stat(filename,&file_info)<0) {
|
|
||||||
fprintf(stderr,"Error! %s not found!\n",filename);
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
file_size=(int)file_info.st_size;
|
|
||||||
|
|
||||||
/* We need to round up to nearest sector size */
|
|
||||||
/* Add an extra sector for the T/S list */
|
|
||||||
/* Then add extra sector for a T/S list every 122*256 bytes (~31k) */
|
|
||||||
needed_sectors=(file_size/BYTES_PER_SECTOR)+ /* round sectors */
|
|
||||||
((file_size%BYTES_PER_SECTOR)!=0)+/* tail if needed */
|
|
||||||
1+/* first T/S list */
|
|
||||||
(file_size/(122*BYTES_PER_SECTOR)); /* extra t/s lists */
|
|
||||||
|
|
||||||
/* Get free space on device */
|
|
||||||
free_space=dos33_free_space(fd);
|
|
||||||
|
|
||||||
/* Check for free space */
|
if (apple_filename[0]<64) {
|
||||||
if (needed_sectors*BYTES_PER_SECTOR>free_space) {
|
fprintf(stderr,"Error! First char of filename "
|
||||||
fprintf(stderr,"Error! Not enough free space on disk image (need %d have %d)\n",
|
"must be ASCII 64 or above!\n");
|
||||||
needed_sectors*BYTES_PER_SECTOR,free_space);
|
return ERROR_INVALID_FILENAME;
|
||||||
exit(4);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* plus one because we need a sector for the tail */
|
/* Check for comma in filename */
|
||||||
size_in_sectors=(file_size/BYTES_PER_SECTOR)+
|
for(i=0;i<strlen(apple_filename);i++) {
|
||||||
((file_size%BYTES_PER_SECTOR)!=0);
|
if (apple_filename[i]==',') {
|
||||||
// printf("Need to allocate %i data sectors\n",size_in_sectors);
|
fprintf(stderr,"Error! "
|
||||||
// printf("Need to allocate %i total sectors\n",needed_sectors);
|
"Cannot have , in a filename!\n");
|
||||||
|
return ERROR_INVALID_FILENAME;
|
||||||
/* Open the local file */
|
}
|
||||||
input_fd=open(filename,O_RDONLY);
|
}
|
||||||
if (input_fd<0) {
|
|
||||||
fprintf(stderr,"Error! could not open %s\n",filename);
|
/* FIXME */
|
||||||
return -1;
|
/* check type */
|
||||||
}
|
/* and sanity check a/b filesize is set properly */
|
||||||
|
|
||||||
|
/* Determine size of file to upload */
|
||||||
|
if (stat(filename,&file_info)<0) {
|
||||||
|
fprintf(stderr,"Error! %s not found!\n",filename);
|
||||||
|
return ERROR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_size=(int)file_info.st_size;
|
||||||
|
|
||||||
|
if (debug) printf("Filesize: %d\n",file_size);
|
||||||
|
|
||||||
|
/* We need to round up to nearest sector size */
|
||||||
|
/* Add an extra sector for the T/S list */
|
||||||
|
/* Then add extra sector for a T/S list every 122*256 bytes (~31k) */
|
||||||
|
needed_sectors=(file_size/BYTES_PER_SECTOR)+ /* round sectors */
|
||||||
|
((file_size%BYTES_PER_SECTOR)!=0)+/* tail if needed */
|
||||||
|
1+/* first T/S list */
|
||||||
|
(file_size/(122*BYTES_PER_SECTOR)); /* extra t/s lists */
|
||||||
|
|
||||||
|
/* Get free space on device */
|
||||||
|
free_space=dos33_free_space(fd);
|
||||||
|
|
||||||
|
/* Check for free space */
|
||||||
|
if (needed_sectors*BYTES_PER_SECTOR>free_space) {
|
||||||
|
fprintf(stderr,"Error! Not enough free space "
|
||||||
|
"on disk image (need %d have %d)\n",
|
||||||
|
needed_sectors*BYTES_PER_SECTOR,free_space);
|
||||||
|
return ERROR_NO_SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* plus one because we need a sector for the tail */
|
||||||
|
size_in_sectors=(file_size/BYTES_PER_SECTOR)+
|
||||||
|
((file_size%BYTES_PER_SECTOR)!=0);
|
||||||
|
if (debug) printf("Need to allocate %i data sectors\n",size_in_sectors);
|
||||||
|
if (debug) printf("Need to allocate %i total sectors\n",needed_sectors);
|
||||||
|
|
||||||
|
/* Open the local file */
|
||||||
|
input_fd=open(filename,O_RDONLY);
|
||||||
|
if (input_fd<0) {
|
||||||
|
fprintf(stderr,"Error! could not open %s\n",filename);
|
||||||
|
return ERROR_IMAGE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
i=0;
|
||||||
|
while (i<size_in_sectors) {
|
||||||
|
|
||||||
i=0;
|
|
||||||
while (i<size_in_sectors) {
|
|
||||||
|
|
||||||
/* Create new T/S list if necessary */
|
/* Create new T/S list if necessary */
|
||||||
if (i%TSL_MAX_NUMBER==0) {
|
if (i%TSL_MAX_NUMBER==0) {
|
||||||
old_ts_list=ts_list;
|
old_ts_list=ts_list;
|
||||||
|
|
||||||
|
/* allocate a sector for the new list */
|
||||||
|
ts_list=dos33_allocate_sector(fd);
|
||||||
|
sectors_used++;
|
||||||
|
if (ts_list<0) return -1;
|
||||||
|
|
||||||
/* allocate a sector for the new list */
|
|
||||||
ts_list=dos33_allocate_sector(fd);
|
|
||||||
sectors_used++;
|
|
||||||
if (ts_list<0) return -1;
|
|
||||||
|
|
||||||
/* clear the t/s sector */
|
/* clear the t/s sector */
|
||||||
for(x=0;x<BYTES_PER_SECTOR;x++) sector_buffer[x]=0;
|
for(x=0;x<BYTES_PER_SECTOR;x++) sector_buffer[x]=0;
|
||||||
lseek(fd,DISK_OFFSET((ts_list>>8)&0xff,ts_list&0xff),SEEK_SET);
|
lseek(fd,DISK_OFFSET((ts_list>>8)&0xff,ts_list&0xff),SEEK_SET);
|
||||||
@ -578,43 +589,50 @@ static int dos33_add_file(int fd,char type,char *filename,
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add new file to Catalog */
|
/* Add new file to Catalog */
|
||||||
|
|
||||||
/* read in vtoc */
|
/* read in vtoc */
|
||||||
dos33_read_vtoc(fd);
|
dos33_read_vtoc(fd);
|
||||||
|
|
||||||
catalog_track=sector_buffer[VTOC_CATALOG_T];
|
catalog_track=sector_buffer[VTOC_CATALOG_T];
|
||||||
catalog_sector=sector_buffer[VTOC_CATALOG_S];
|
catalog_sector=sector_buffer[VTOC_CATALOG_S];
|
||||||
|
|
||||||
continue_parsing_catalog:
|
continue_parsing_catalog:
|
||||||
|
|
||||||
/* Read in Catalog Sector */
|
/* Read in Catalog Sector */
|
||||||
lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET);
|
lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET);
|
||||||
result=read(fd,sector_buffer,BYTES_PER_SECTOR);
|
result=read(fd,sector_buffer,BYTES_PER_SECTOR);
|
||||||
|
|
||||||
/* Find empty directory entry */
|
|
||||||
i=0;
|
|
||||||
while(i<7) {
|
|
||||||
if ((sector_buffer[CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE)]==0xff) ||
|
|
||||||
(sector_buffer[CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE)]==0x00))
|
|
||||||
goto got_a_dentry;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((catalog_track=0x11) && (catalog_sector==1)) {
|
|
||||||
/* in theory can only have 105 files */
|
|
||||||
/* if full, we have no recourse! */
|
|
||||||
/* can we allocate new catalog sectors and point to them?? */
|
|
||||||
fprintf(stderr,"Error! No more room for files!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
catalog_track=sector_buffer[CATALOG_NEXT_T];
|
/* Find empty directory entry */
|
||||||
catalog_sector=sector_buffer[CATALOG_NEXT_S];
|
i=0;
|
||||||
|
while(i<7) {
|
||||||
|
/* for undelete purposes might want to skip 0xff */
|
||||||
|
/* (deleted) files first and only use if no room */
|
||||||
|
|
||||||
|
if ((sector_buffer[CATALOG_FILE_LIST+
|
||||||
|
(i*CATALOG_ENTRY_SIZE)]==0xff) ||
|
||||||
|
(sector_buffer[CATALOG_FILE_LIST+
|
||||||
|
(i*CATALOG_ENTRY_SIZE)]==0x00)) {
|
||||||
|
goto got_a_dentry;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((catalog_track=0x11) && (catalog_sector==1)) {
|
||||||
|
/* in theory can only have 105 files */
|
||||||
|
/* if full, we have no recourse! */
|
||||||
|
/* can we allocate new catalog sectors */
|
||||||
|
/* and point to them?? */
|
||||||
|
fprintf(stderr,"Error! No more room for files!\n");
|
||||||
|
return ERROR_CATALOG_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
catalog_track=sector_buffer[CATALOG_NEXT_T];
|
||||||
|
catalog_sector=sector_buffer[CATALOG_NEXT_S];
|
||||||
|
|
||||||
|
goto continue_parsing_catalog;
|
||||||
|
|
||||||
goto continue_parsing_catalog;
|
|
||||||
|
|
||||||
got_a_dentry:
|
got_a_dentry:
|
||||||
// printf("Adding file at entry %i of catalog 0x%x:0x%x\n",
|
// printf("Adding file at entry %i of catalog 0x%x:0x%x\n",
|
||||||
// i,catalog_track,catalog_sector);
|
// i,catalog_track,catalog_sector);
|
||||||
@ -1311,14 +1329,14 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dos33_load_file(dos_fd,catalog_entry,output_filename);
|
dos33_load_file(dos_fd,catalog_entry,output_filename);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMMAND_CATALOG:
|
case COMMAND_CATALOG:
|
||||||
|
|
||||||
/* get first catalog */
|
/* get first catalog */
|
||||||
catalog_entry=dos33_get_catalog_ts(dos_fd);
|
catalog_entry=dos33_get_catalog_ts(dos_fd);
|
||||||
|
|
||||||
printf("\nDISK VOLUME %i\n\n",sector_buffer[VTOC_DISK_VOLUME]);
|
printf("\nDISK VOLUME %i\n\n",sector_buffer[VTOC_DISK_VOLUME]);
|
||||||
while(catalog_entry>0) {
|
while(catalog_entry>0) {
|
||||||
catalog_entry=dos33_find_next_file(dos_fd,catalog_entry);
|
catalog_entry=dos33_find_next_file(dos_fd,catalog_entry);
|
||||||
@ -1330,35 +1348,36 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMMAND_SAVE:
|
case COMMAND_SAVE:
|
||||||
|
/* argv3 == type == A,B,T,I,N,L etc */
|
||||||
/* argv3 == type == A,B,T,I,N,L etc */
|
/* argv4 == name of local file */
|
||||||
/* argv4 == name of local file */
|
/* argv5 == optional name of file on disk image */
|
||||||
/* argv5 == optional name of file on disk image */
|
|
||||||
|
if (argc<5+extra_ops) {
|
||||||
if (argc<5+extra_ops) {
|
fprintf(stderr,"Error! Need type and file_name\n");
|
||||||
fprintf(stderr,"Error! Need type and file_name\n");
|
fprintf(stderr,"%s %s SAVE type "
|
||||||
fprintf(stderr,"%s %s SAVE type file_name apple_filename\n",
|
"file_name apple_filename\n",
|
||||||
argv[0],image);
|
argv[0],image);
|
||||||
goto exit_and_close;
|
goto exit_and_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
type=argv[firstarg+2][0];
|
type=argv[firstarg+2][0];
|
||||||
|
|
||||||
if (argc==6+extra_ops) {
|
if (argc==6+extra_ops) {
|
||||||
if (strlen(argv[firstarg+4])>30) {
|
if (strlen(argv[firstarg+4])>30) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Warning! Truncating filename to 30 chars!\n");
|
"Warning! Truncating filename "
|
||||||
}
|
"to 30 chars!\n");
|
||||||
strncpy(apple_filename,argv[firstarg+4],30);
|
}
|
||||||
apple_filename[30]=0;
|
strncpy(apple_filename,argv[firstarg+4],30);
|
||||||
}
|
apple_filename[30]=0;
|
||||||
else {
|
}
|
||||||
/* If no filename specified for apple name */
|
else {
|
||||||
/* Then use the input name. Note, we strip */
|
/* If no filename specified for apple name */
|
||||||
/* everything up to the last slash so useless */
|
/* Then use the input name. Note, we strip */
|
||||||
/* path info isn't used */
|
/* everything up to the last slash so useless */
|
||||||
|
/* path info isn't used */
|
||||||
{
|
{
|
||||||
char *temp;
|
char *temp;
|
||||||
temp=argv[firstarg+3]+(strlen(argv[firstarg+3])-1);
|
temp=argv[firstarg+3]+(strlen(argv[firstarg+3])-1);
|
||||||
@ -1398,9 +1417,9 @@ int main(int argc, char **argv) {
|
|||||||
dos33_delete_file(dos_fd,catalog_entry);
|
dos33_delete_file(dos_fd,catalog_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
dos33_add_file(dos_fd,type,argv[firstarg+3],apple_filename);
|
dos33_add_file(dos_fd,type,argv[firstarg+3],apple_filename);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMMAND_DELETE:
|
case COMMAND_DELETE:
|
||||||
if (argc+extra_ops<4) {
|
if (argc+extra_ops<4) {
|
||||||
|
@ -7,45 +7,45 @@
|
|||||||
|
|
||||||
#include "dos33.h"
|
#include "dos33.h"
|
||||||
|
|
||||||
void usage(char *binary,int help) {
|
static void usage(char *binary,int help) {
|
||||||
|
|
||||||
printf("\n%s - version %s\n",binary,VERSION);
|
printf("\n%s - version %s\n",binary,VERSION);
|
||||||
printf("\tby Vince Weaver <vince@deater.net>\n");
|
printf("\tby Vince Weaver <vince@deater.net>\n");
|
||||||
printf("\thttp://www.deater.net/weave/vmwprod/apple/\n\n");
|
printf("\thttp://www.deater.net/weave/vmwprod/apple/\n\n");
|
||||||
if (help) {
|
if (help) {
|
||||||
printf("Usage:\t%s [-t track] [-s sector] [-b size] "
|
printf("Usage:\t%s [-t track] [-s sector] [-b size] "
|
||||||
"[-d filename] [-f filename] device_name\n\n",binary);
|
"[-d filename] [-f filename] device_name\n\n",binary);
|
||||||
printf("\t-t tracks : number of tracks in filesystem\n");
|
printf("\t-t tracks : number of tracks in filesystem\n");
|
||||||
printf("\t-s sectors : number of sectors in filesystem\n");
|
printf("\t-s sectors : number of sectors in filesystem\n");
|
||||||
printf("\t-b blocksize : size of sector, in bytes\n");
|
printf("\t-b blocksize : size of sector, in bytes\n");
|
||||||
printf("\t-d filename : file to copy first 3 tracks over from\n");
|
printf("\t-d filename : file to copy first 3 tracks over from\n");
|
||||||
printf("\t-f filename : name of BASIC file to autoboot. Default is HELLO\n");
|
printf("\t-f filename : name of BASIC file to autoboot. Default is HELLO\n");
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
int num_tracks=35,num_sectors=16,block_size=256;
|
|
||||||
int fd,dos_fd;
|
|
||||||
char device[BUFSIZ],dos_src[BUFSIZ];
|
|
||||||
char *buffer,*endptr;
|
|
||||||
int i,c,copy_dos=0;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
char boot_filename[30]="HELLO ";
|
int num_tracks=35,num_sectors=16,block_size=256;
|
||||||
|
int fd,dos_fd;
|
||||||
/* Parse Command Line Arguments */
|
char device[BUFSIZ],dos_src[BUFSIZ];
|
||||||
|
char *buffer,*endptr;
|
||||||
|
int i,c,copy_dos=0;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
char boot_filename[30]="HELLO ";
|
||||||
|
|
||||||
|
/* Parse Command Line Arguments */
|
||||||
|
|
||||||
while ((c = getopt (argc, argv,"t:s:b:d:f:hv"))!=-1) {
|
while ((c = getopt (argc, argv,"t:s:b:d:f:hv"))!=-1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
||||||
case 't': num_tracks=strtol(optarg,&endptr,10);
|
case 't': num_tracks=strtol(optarg,&endptr,10);
|
||||||
if ( endptr == optarg ) usage(argv[0], 1);
|
if ( endptr == optarg ) usage(argv[0], 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's': num_sectors=strtol(optarg,&endptr,10);
|
case 's': num_sectors=strtol(optarg,&endptr,10);
|
||||||
if ( endptr == optarg ) usage(argv[0], 1);
|
if ( endptr == optarg ) usage(argv[0], 1);
|
||||||
break;
|
break;
|
||||||
@ -56,7 +56,7 @@ int main(int argc, char **argv) {
|
|||||||
case 'd': copy_dos=1;
|
case 'd': copy_dos=1;
|
||||||
strncpy(dos_src,optarg,BUFSIZ);
|
strncpy(dos_src,optarg,BUFSIZ);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
if (strlen(optarg)>30) {
|
if (strlen(optarg)>30) {
|
||||||
fprintf(stderr,"Auto boot filename too long!\n");
|
fprintf(stderr,"Auto boot filename too long!\n");
|
||||||
@ -69,90 +69,89 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
case 'v': usage(argv[0],0);
|
case 'v': usage(argv[0],0);
|
||||||
case 'h': usage(argv[0],1);
|
case 'h': usage(argv[0],1);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind==argc) {
|
|
||||||
printf("Error! Must include device name\n\n");
|
|
||||||
goto end_of_program;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(device,argv[optind],BUFSIZ);
|
|
||||||
|
|
||||||
/* Sanity check values */
|
|
||||||
|
|
||||||
/* s 2->32 (limited by 4-byte bitfields) */
|
|
||||||
if ((num_sectors<2) || (num_sectors>32)) {
|
|
||||||
printf("Number of sectors must be >2 and <=32\n\n");
|
|
||||||
goto end_of_program;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* t 17->(block_size-0x38)/2 */
|
if (optind==argc) {
|
||||||
if ((num_tracks<18) || (num_tracks>(block_size-0x38)/2)) {
|
printf("Error! Must include device name\n\n");
|
||||||
printf("Number of tracks must be >18 and <=%i (block_size-0x38)/2\n\n",
|
goto end_of_program;
|
||||||
(block_size-0x38)/2);
|
}
|
||||||
goto end_of_program;
|
|
||||||
}
|
strncpy(device,argv[optind],BUFSIZ);
|
||||||
|
|
||||||
/* sector_size 256->65536 (or 512 basedon one bye t/s size field?) */
|
/* Sanity check values */
|
||||||
if ((block_size<256)||(block_size>65536)) {
|
|
||||||
printf("Block size must be >=256 and <65536\n\n");
|
/* s 2->32 (limited by 4-byte bitfields) */
|
||||||
goto end_of_program;
|
if ((num_sectors<2) || (num_sectors>32)) {
|
||||||
}
|
printf("Number of sectors must be >2 and <=32\n\n");
|
||||||
|
goto end_of_program;
|
||||||
|
}
|
||||||
buffer=calloc(1,sizeof(char)*block_size);
|
|
||||||
|
/* t 17->(block_size-0x38)/2 */
|
||||||
|
if ((num_tracks<18) || (num_tracks>(block_size-0x38)/2)) {
|
||||||
|
printf("Number of tracks must be >18 and <=%i (block_size-0x38)/2\n\n",
|
||||||
|
(block_size-0x38)/2);
|
||||||
|
goto end_of_program;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sector_size 256->65536 (or 512 basedon one bye t/s size field?) */
|
||||||
|
if ((block_size<256)||(block_size>65536)) {
|
||||||
|
printf("Block size must be >=256 and <65536\n\n");
|
||||||
|
goto end_of_program;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer=calloc(1,sizeof(char)*block_size);
|
||||||
|
|
||||||
/* Open device */
|
/* Open device */
|
||||||
fd=open(device,O_RDWR|O_CREAT,0666);
|
fd=open(device,O_RDWR|O_CREAT,0666);
|
||||||
if (fd<0) {
|
if (fd<0) {
|
||||||
fprintf(stderr,"Error opening %s\n",device);
|
fprintf(stderr,"Error opening %s\n",device);
|
||||||
goto end_of_program;
|
goto end_of_program;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* zero out file */
|
|
||||||
for(i=0;i<num_tracks*num_sectors;i++) {
|
|
||||||
result=write(fd,buffer,block_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy over OS from elsewhere, if desired */
|
/* zero out file */
|
||||||
if (copy_dos) {
|
for(i=0;i<num_tracks*num_sectors;i++) {
|
||||||
|
result=write(fd,buffer,block_size);
|
||||||
dos_fd=open(dos_src,O_RDONLY);
|
}
|
||||||
if (fd<0) {
|
|
||||||
fprintf(stderr,"Error opening %s\n",dos_src);
|
|
||||||
goto end_of_program;
|
|
||||||
}
|
|
||||||
lseek(fd,0,SEEK_SET);
|
|
||||||
/* copy first 3 sectors */
|
|
||||||
for(i=0;i<3*(num_sectors);i++) {
|
|
||||||
result=read(dos_fd,buffer,block_size);
|
|
||||||
result=write(fd,buffer,block_size);
|
|
||||||
}
|
|
||||||
close(dos_fd);
|
|
||||||
|
|
||||||
/* Set boot filename */
|
|
||||||
|
|
||||||
/* Track 1 sector 9 */
|
|
||||||
lseek(fd,((1*num_sectors)+9)*block_size,SEEK_SET);
|
|
||||||
result=read(fd,buffer,block_size);
|
|
||||||
|
|
||||||
/* filename begins at offset 75 */
|
|
||||||
for(i=0;i<30;i++) {
|
|
||||||
buffer[0x75+i]=boot_filename[i]|0x80;
|
|
||||||
}
|
|
||||||
lseek(fd,((1*num_sectors)+9)*block_size,SEEK_SET);
|
|
||||||
result=write(fd,buffer,block_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear buffer */
|
/* Copy over OS from elsewhere, if desired */
|
||||||
for(i=0;i<block_size;i++) buffer[i]=0;
|
if (copy_dos) {
|
||||||
|
dos_fd=open(dos_src,O_RDONLY);
|
||||||
|
if (fd<0) {
|
||||||
|
fprintf(stderr,"Error opening %s\n",dos_src);
|
||||||
|
goto end_of_program;
|
||||||
|
}
|
||||||
|
lseek(fd,0,SEEK_SET);
|
||||||
|
/* copy first 3 sectors */
|
||||||
|
for(i=0;i<3*(num_sectors);i++) {
|
||||||
|
result=read(dos_fd,buffer,block_size);
|
||||||
|
result=write(fd,buffer,block_size);
|
||||||
|
}
|
||||||
|
close(dos_fd);
|
||||||
|
|
||||||
|
/* Set boot filename */
|
||||||
|
|
||||||
|
/* Track 1 sector 9 */
|
||||||
|
lseek(fd,((1*num_sectors)+9)*block_size,SEEK_SET);
|
||||||
|
result=read(fd,buffer,block_size);
|
||||||
|
|
||||||
|
/* filename begins at offset 75 */
|
||||||
|
for(i=0;i<30;i++) {
|
||||||
|
buffer[0x75+i]=boot_filename[i]|0x80;
|
||||||
|
}
|
||||||
|
lseek(fd,((1*num_sectors)+9)*block_size,SEEK_SET);
|
||||||
|
result=write(fd,buffer,block_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear buffer */
|
||||||
|
for(i=0;i<block_size;i++) buffer[i]=0;
|
||||||
|
|
||||||
/* Create VTOC */
|
/* Create VTOC */
|
||||||
buffer[VTOC_DOS_RELEASE]=0x3; /* fake dos 3.3 */
|
buffer[VTOC_DOS_RELEASE]=0x3; /* fake dos 3.3 */
|
||||||
buffer[VTOC_CATALOG_T]=0x11;
|
buffer[VTOC_CATALOG_T]=0x11;
|
||||||
buffer[VTOC_CATALOG_S]=0xf; /* 1st Catalog typically at 0x11/0xf */
|
buffer[VTOC_CATALOG_S]=num_sectors-1;
|
||||||
|
/* 1st Catalog typically at 0x11/0xf */
|
||||||
buffer[VTOC_DISK_VOLUME]=254; /* typical volume 254 */
|
buffer[VTOC_DISK_VOLUME]=254; /* typical volume 254 */
|
||||||
buffer[VTOC_MAX_TS_PAIRS]=((block_size-0xc)/2)&0xff;
|
buffer[VTOC_MAX_TS_PAIRS]=((block_size-0xc)/2)&0xff;
|
||||||
/* Number of T/S pairs fitting */
|
/* Number of T/S pairs fitting */
|
||||||
@ -205,10 +204,22 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
/* Write out VTOC to disk */
|
/* Write out VTOC to disk */
|
||||||
lseek(fd,((17*num_sectors)+0)*block_size,SEEK_SET);
|
lseek(fd,((17*num_sectors)+0)*block_size,SEEK_SET);
|
||||||
result=write(fd,buffer,block_size);
|
|
||||||
|
|
||||||
|
result=write(fd,buffer,block_size);
|
||||||
if (result<0) fprintf(stderr,"Error writing!\n");
|
if (result<0) fprintf(stderr,"Error writing!\n");
|
||||||
|
|
||||||
|
/* clear buffer */
|
||||||
|
for(i=0;i<block_size;i++) buffer[i]=0;
|
||||||
|
/* Set catalog next pointers */
|
||||||
|
for(i=(num_sectors-1);i>1;i--) {
|
||||||
|
buffer[1]=0x11;
|
||||||
|
buffer[2]=i-1;
|
||||||
|
|
||||||
|
lseek(fd,((17*num_sectors)+i)*block_size,SEEK_SET);
|
||||||
|
result=write(fd,buffer,block_size);
|
||||||
|
if (result<0) fprintf(stderr,"Error writing!\n");
|
||||||
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
end_of_program:
|
end_of_program:
|
||||||
|
@ -1 +1 @@
|
|||||||
#define VERSION "0.0.11"
|
#define VERSION "0.0.12"
|
||||||
|
Loading…
Reference in New Issue
Block a user