mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-14 15:45:23 +00:00
FSIO: bug fixes and the addition of OS/8 support
This commit is contained in:
parent
f40e814fcb
commit
beabfab2e8
35
converters/fsio/Changes
Normal file
35
converters/fsio/Changes
Normal file
@ -0,0 +1,35 @@
|
||||
Changes Since Alpha Release:
|
||||
|
||||
1. mount: Fix memory leak when file system verification fails
|
||||
|
||||
2. dos11: Fix hang when parsing wildcard programmer number
|
||||
|
||||
3. Migrate to using GNU readline library for command line editing etc
|
||||
|
||||
4. local: Fix buffering so that local "type" command works
|
||||
|
||||
5. Add DOS-11 magtape support using file system type "dosmt"
|
||||
|
||||
6. newfs: Remove -a switch. Replace with "-t type" switch to allow more
|
||||
flexibility. The equivalent of "-a" is now "-t rl02".
|
||||
|
||||
12-Jun-19
|
||||
|
||||
- Added support for sector interleave on RX01/RX02 drives
|
||||
|
||||
- Now supports creating RX01-sized container files
|
||||
- Now works with RTFLX on TOPS-10 with RX02-sized container files
|
||||
(documentation updated)
|
||||
|
||||
25-Jun-19
|
||||
|
||||
- Added support for OS/8 file systems on RX01, RX02 and RK05 drives using
|
||||
file system type "os8"
|
||||
|
||||
- Added support for creating RT-11 file systems with additional space
|
||||
allocated to each directory entry
|
||||
|
||||
9-Jan-20
|
||||
|
||||
- Merged change from tvrusso to fix compilation on FreeBSD
|
||||
|
||||
@ -7,13 +7,14 @@ INSTALL=install
|
||||
CC=gcc
|
||||
|
||||
EXECUTABLE=fsio
|
||||
SOURCES=fsio.c declib.c tape.c dos11.c rt11.c dosmt.c local.c
|
||||
INCLUDES=fsio.h declib.h tape.h dos11.h rt11.h dosmt.h
|
||||
SOURCES=fsio.c declib.c tape.c dos11.c rt11.c dosmt.c local.c os8.c
|
||||
INCLUDES=fsio.h declib.h tape.h dos11.h rt11.h dosmt.h os8.h
|
||||
LIBS=-lreadline
|
||||
MANPAGE=fsio.1
|
||||
MANPAGE_DOS=fsio-dos11.1
|
||||
MANPAGE_RT=fsio-rt11.1
|
||||
MANPAGE_DOSMT=fsio-dosmt.1
|
||||
MANPAGE_OS8=fsio-os8.1
|
||||
ARCHIVE=fsio.tgz
|
||||
|
||||
RELEASEFILES=$(BIN)/$(EXECUTABLE)
|
||||
@ -21,6 +22,7 @@ RELEASEFILES+=$(MAN)/$(MANPAGE)
|
||||
RELEASEFILES+=$(MAN)/$(MANPAGE_DOS)
|
||||
RELEASEFILES+=$(MAN)/$(MANPAGE_RT)
|
||||
RELEASEFILES+=$(MAN)/$(MANPAGE_DOSMT)
|
||||
RELEASEFILES+=$(MAN)/$(MANPAGE_OS8)
|
||||
RELEASEFILES+=./fsio.txt ./fsioSimh.txt
|
||||
|
||||
$(EXECUTABLE): $(SOURCES) $(INCLUDES) Makefile
|
||||
@ -38,6 +40,7 @@ install: $(EXECUTABLE) $(MANPAGE) $(MANPAGE_DOS) $(MANPAGE_RT)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE_DOS) $(MAN)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE_RT) $(MAN)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE_DOSMT) $(MAN)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE_OS8) $(MAN)
|
||||
|
||||
uninstall:
|
||||
rm -f $(BIN)/$(EXECUTABLE)
|
||||
@ -45,6 +48,7 @@ uninstall:
|
||||
rm -f $(MAN)/$(MANPAGE_DOS)
|
||||
rm -f $(MAN)/$(MANPAGE_RT)
|
||||
rm -f $(MAN)/$(MANPAGE_DOSMT)
|
||||
rm -f $(MAN)/$(MANPAGE_OS8)
|
||||
|
||||
# This assumes that fsio has been "installed" on the current system
|
||||
archive: $(RELEASEFILES)
|
||||
|
||||
@ -1666,12 +1666,12 @@ static void dos11Umount(
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Size of the container file in blocks of default file system size
|
||||
* Default size of the container file in bytes (RK05).
|
||||
*
|
||||
--*/
|
||||
static size_t dos11Size(void)
|
||||
{
|
||||
return DISKSIZE_RK05;
|
||||
return DISKSIZE_RK05 * BLOCKSIZE_RK11;
|
||||
}
|
||||
|
||||
/*++
|
||||
@ -1707,7 +1707,7 @@ static int dos11Newfs(
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
data->blocks = size;
|
||||
data->blocks = size / BLOCKSIZE_RK11;
|
||||
data->bitmaps = 5;
|
||||
data->bmblk[0] = MAP_BLOCK;
|
||||
data->bmblk[1] = MAP_BLOCK + 1;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH FSIO-DOS11 1 "December 28,2018" "FFS I/O - DOS-11"
|
||||
.TH FSIO-DOS11 1 "Jun 21,2019" "FFS I/O - DOS-11"
|
||||
.SH NAME
|
||||
fsio-dos11 \- Foreign File System I/O - DOS-11
|
||||
.br
|
||||
@ -45,6 +45,7 @@ Creates an empty UFD and sets default UIC for file access.
|
||||
.BR fsio (1),
|
||||
.BR fsio-rt11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-os8 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH FSIO-DOSMT 1 "January 28,2019" "FFS I/O - DOS-11 magtape"
|
||||
.TH FSIO-DOSMT 1 "Jun 25,2019" "FFS I/O - DOS-11 magtape"
|
||||
.SH NAME
|
||||
fsio-dosmt \- Foreign File System I/O - DOS-11 magtape
|
||||
.br
|
||||
@ -102,9 +102,10 @@ the end of any specific file (see info command for more details on how to
|
||||
determine the current tape position).
|
||||
.br
|
||||
.SH SEE ALSO
|
||||
.BR fsio (1),
|
||||
.BR fsio (1)
|
||||
.BR fsio-dos11 (1)
|
||||
.BR fsio-rt11 (1)
|
||||
.BR fsio-os8 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
80
converters/fsio/fsio-os8.1
Normal file
80
converters/fsio/fsio-os8.1
Normal file
@ -0,0 +1,80 @@
|
||||
.TH FSIO-OS8 1 "Sep 218,2019" "FFS I/O - OS/8"
|
||||
.SH NAME
|
||||
fsio-os8 \- Foreign File System I/O - OS/8
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
\fBfsio\fP allows access to OS/8 file systems using the file system type
|
||||
"\fIos8\fP"
|
||||
.br
|
||||
.SH OS/8 PHYSICAL DISKS
|
||||
OS/8 uses a file system block size of 256 words and OS/8 devices are limited
|
||||
to 4095 blocks. Blocks 0 through 6 are reserved so the largest possible file
|
||||
is 4088 blocks long (1046528 words). Larger devices, for example the RK05,
|
||||
place multiple file systems on each physical device.
|
||||
|
||||
.br
|
||||
OS/8 does not write any type of signature on the device and each device type
|
||||
has it's own partitioning scheme so the \fImount\fP command must use the
|
||||
"\fI-f type\fP switch so that \fBfsio\fP can determine the file system
|
||||
layout. \fBfsio\fP uses a set of heuristics to verify the integrity of
|
||||
the OS/8 file system(s) but it is quite possible for a random disk to pass
|
||||
these tests and later crash \fBfsio\fP.
|
||||
.SH MOUNT OPERATION
|
||||
\fImount\fP requires the "\fI-f type\fP" switch so that it can determine the
|
||||
type of the underlying disk (See NEWFS OPERATION below for details).
|
||||
.SH NEWFS OPERATION
|
||||
\fInewfs\fP creates an RK05 disk image with 2 file systems. If the
|
||||
"\fI-f type\fP" switch is present a different container file will be created
|
||||
depending on the type of the device specified:
|
||||
.br
|
||||
.RS
|
||||
.TP
|
||||
\fIrk05\fP \- RK05 image (2 file systems, 3248 blocks each)
|
||||
.br
|
||||
.TP
|
||||
\fIrx01\fP \- RX01 image (single file system, 494 blocks)
|
||||
.br
|
||||
.TP
|
||||
\fIrx02\fP \- RX02 image (single file system, 988 blocks)
|
||||
.br
|
||||
.RE
|
||||
|
||||
Note that in order to use RX02 media the OS/8 system must have the device
|
||||
extensions kit installed.
|
||||
.br
|
||||
|
||||
The "\fI-e extra\fP" switch, where "extra" is a number in the range 0 - 63,
|
||||
may be used to create file systems with "extra" additional information words
|
||||
available to each directory entry. By default, \fInewfs\fP will create file
|
||||
systems with 1 additional information word which will be used to hold the
|
||||
file creation date. If you do not want any additional information words
|
||||
use "\fI-e 0\fP".
|
||||
.br
|
||||
.SH SET OPERATION
|
||||
The following \fIset\fP commands are supported:
|
||||
.br
|
||||
.TP
|
||||
.B "\fIyear\fP n"
|
||||
.br
|
||||
|
||||
All subsequent OS/8 file creations will include a creation date (if the file
|
||||
system was created with at least 1 additional information word). The date used
|
||||
will be the month and day of the month for today with the year "n" (where "n"
|
||||
is in the range 0 - 7).
|
||||
.br
|
||||
.TP
|
||||
.B "\fIyear\fP none"
|
||||
.br
|
||||
|
||||
All subsequent OS/8 file creations will include a zero creation date (if the
|
||||
file system was created with at least 1 additional information word). This is
|
||||
the default state after mount.
|
||||
.br
|
||||
.SH SEE ALSO
|
||||
.BR fsio (1)
|
||||
.BR fsio-dos11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-rt11 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
@ -1,4 +1,4 @@
|
||||
.TH FSIO-RT11 1 "May 15,2019" "FFS I/O - RT-11"
|
||||
.TH FSIO-RT11 1 "Jun 25,2019" "FFS I/O - RT-11"
|
||||
.SH NAME
|
||||
fsio-rt11 \- Foreign File System I/O - RT-11
|
||||
.br
|
||||
@ -23,6 +23,15 @@ version 2 file systems.
|
||||
The VMS exchange utility may be used to initialize an RT-11 volume but writes
|
||||
it's own unique signature in the home block. \fBfsio\fP is able to correctly
|
||||
handle this signature.
|
||||
.br
|
||||
.SH RT-11 PHYSICAL DISKS
|
||||
RT-11 uses a file system block size of 512 bytes and most disk type either
|
||||
have a block size of 512 bytes or use 2 contiguous blocks or 256 bytes each.
|
||||
Floppy diskettes, RX01 and RX02 drives, use small sectors size and for
|
||||
performance reason, adjacent logical sectors are interleaved within the same
|
||||
track. When mounting a floppy diskette, the \fI"-f type"\fP must be used so
|
||||
that \fIfsio\fP can determine the interleaving used. In this case "type"
|
||||
should be either "rx01" or "rx02".
|
||||
.SH LOGICAL DISKS
|
||||
\fBfsio\fP can be used to access an RT-11 logical disk if the file has been
|
||||
copied to the host file system.
|
||||
@ -43,9 +52,18 @@ depending on the type of device specified:
|
||||
\fIrl02\fP \- RL02 image (10MB, 20480 blocks)
|
||||
.br
|
||||
.TP
|
||||
\fIrx20\fP \- RX20 image (512KB, 1024 blocks)
|
||||
\fIrx01\fP \- RX01 floopy image (256KB, 2002 sectors of 128 bytes)
|
||||
.br
|
||||
.TP
|
||||
\fIrx02\fP \- RX02 floopy image (512KB, 2002 sectors of 256 bytes)
|
||||
.br
|
||||
.RE
|
||||
|
||||
The "\fI-e extra\fP" switch, where "extra" is a number in the range 0 - 63,
|
||||
may be used to create file systems with "extra" additional bytes available to
|
||||
each directory entry. \fIfsio\fP will silently round up the value to make it
|
||||
an even number required by RT-11. By default, \fInewfs\fP will create file
|
||||
systems with no additional bytes for each directory entry.
|
||||
.SH COPY OPERATION
|
||||
When copying in ASCII mode, \fBfsio\fP will normally write ^Z (octal 032) to
|
||||
indicate the end-of-file. Some utilities, such as FLX on RSX-11, cannot
|
||||
@ -56,9 +74,10 @@ NULLs up to the next block boundary if this occurs.
|
||||
.SH SET OPERATION
|
||||
No \fIset\fP commands are currently supported.
|
||||
.SH SEE ALSO
|
||||
.BR fsio (1),
|
||||
.BR fsio (1)
|
||||
.BR fsio-dos11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-os8 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH FSIO 1 "May 15,2019" "Foreign File System I/O"
|
||||
.TH FSIO 1 "Sep 17,2019" "Foreign File System I/O"
|
||||
.SH NAME
|
||||
fsio \- Foreign File System I/O
|
||||
.SH SYNOPSIS
|
||||
@ -76,7 +76,7 @@ The following commands are only accepted by file systems which are on magtape de
|
||||
.br
|
||||
.SH COMMANDS
|
||||
.TP
|
||||
.B "\fImount\fP [-dfrx] dev[:] file type"
|
||||
.B "\fImount\fP [-dfrx] [-t type] dev[:] file type"
|
||||
Make the container file available to fsio.
|
||||
.br
|
||||
.RS
|
||||
@ -93,6 +93,8 @@ Make the container file available to fsio.
|
||||
.br
|
||||
.B "\fI\-r\fP \- mount file system read-only"
|
||||
.br
|
||||
.B "\fI\-t type\fP \- specify optional disk type"
|
||||
.br
|
||||
.B "\fI\-x\fP \- dosmt will use extended filenames when writing"
|
||||
.br
|
||||
.B "\fIdev[:]\fP \- user supplied name for the mount"
|
||||
@ -113,13 +115,15 @@ Remove knowledge of the container file from fsio.
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
.B "\fInewfs\fP [-t type] file type"
|
||||
.B "\fInewfs\fP [-t type] [-e count] file type"
|
||||
Create an new container with an empty file system.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-t type\fP \- use alternate, file-system dependent size"
|
||||
.br
|
||||
.B "\fI\-e n\fP \- Specify extra space for directory entries (RT11, OS/8)"
|
||||
.br
|
||||
.B "\fIfile\fP \- name of the container file"
|
||||
.br
|
||||
.B "\fItype\fP \- type of container file system"
|
||||
@ -327,10 +331,13 @@ This function depends on the value of blks:
|
||||
.br
|
||||
.B "\fIdosmt\fP \- container file in DOS-11 magtape format"
|
||||
.br
|
||||
.B "\fIos8\fP \- OS/8 on RX01, RX01 or RK05"
|
||||
.br
|
||||
.SH SEE ALSO
|
||||
.BR fsio-dos11 (1),
|
||||
.BR fsio-rt11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-os8 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Foreign file system interface (12/26/2018)
|
||||
* Foreign file system interface (9/18/2019)
|
||||
*
|
||||
* Each foreign file system is described by a struct FSdef which is linked
|
||||
* into a master list of supported file systems in FSioInit(). Each entry
|
||||
@ -84,7 +84,9 @@
|
||||
* This routine is called when processing a "mount" command. The container
|
||||
* file is open, and this routine should verify that it contains a valid
|
||||
* file system. This routine may print out information about the file
|
||||
* system. Return 1 if the file system is valid, 0 otherwise.
|
||||
* system. Return 1 if the file system is valid, 0 if the file system is
|
||||
* invalid and -1 if the file system is invalid and an erroir message
|
||||
* has already been printed.
|
||||
*
|
||||
* void (*umount)(struct mountedFS *mount);
|
||||
*
|
||||
@ -95,9 +97,8 @@
|
||||
*
|
||||
* size_t (*size)(void)
|
||||
*
|
||||
* Return the number of "blocksz" size blocks used for the container file.
|
||||
* The command line switch (-t type) may be used to determine the
|
||||
* required size.
|
||||
* Return the number of byte used for the container file. The command
|
||||
* line switch (-t type) may be used to override the default size.
|
||||
*
|
||||
* int (*newfs)(struct mountedFS *mount, size_t size);
|
||||
*
|
||||
@ -151,9 +152,9 @@
|
||||
*
|
||||
* off_t (*fileSize)(void *filep);
|
||||
*
|
||||
* Returns the size of a file currently open for reading. If it is
|
||||
* not possible to determine the actual file size, return 0. In all
|
||||
* other cases, the returned value may over-estimate, but not
|
||||
* Returns the size, in bytes, of a file currently open for reading.
|
||||
* If it is not possible to determine the actual file size, return 0.
|
||||
* In all other cases, the returned value may over-estimate, but not
|
||||
* under-estimate the size of the file. For example, linked files
|
||||
* on DOS-11 will overestimate the size by 2 bytes/block.
|
||||
*
|
||||
@ -310,12 +311,12 @@ struct command {
|
||||
cmd_t func; /* Command execution function */
|
||||
} cmdTable[] = {
|
||||
#ifdef DEBUG
|
||||
{ "mount", OPTIONS("dfrx"), 3, 3, 0, doMount },
|
||||
{ "mount", OPTIONS("dfrt:x"), 3, 3, 0, doMount },
|
||||
#else
|
||||
{ "mount", OPTIONS("frx"), 3, 3, 0, doMount },
|
||||
{ "mount", OPTIONS("frt:x"), 3, 3, 0, doMount },
|
||||
#endif
|
||||
{ "umount", NULL, 1, 1, 0, doUmount },
|
||||
{ "newfs", OPTIONS("t:"), 2, 2, 0, doNewfs },
|
||||
{ "newfs", OPTIONS("e:t:"), 2, 2, 0, doNewfs },
|
||||
{ "set", NULL, 2, MAX_CMDLEN, 0, doSet },
|
||||
{ "info", NULL, 1, 1, 0, doInfo },
|
||||
{ "dir", OPTIONS("fn"), 1, 1, 0, doDir },
|
||||
@ -364,6 +365,7 @@ extern struct FSdef localFS;
|
||||
extern struct FSdef dos11FS;
|
||||
extern struct FSdef rt11FS;
|
||||
extern struct FSdef dosmtFS;
|
||||
extern struct FSdef os8FS;
|
||||
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
@ -418,6 +420,9 @@ static void FSioInit(void)
|
||||
|
||||
dosmtFS.next = fileSystems;
|
||||
fileSystems = &dosmtFS;
|
||||
|
||||
os8FS.next = fileSystems;
|
||||
fileSystems = &os8FS;
|
||||
}
|
||||
|
||||
/*++
|
||||
@ -746,6 +751,7 @@ static void doMount(void)
|
||||
{
|
||||
struct FSdef *filesys;
|
||||
FILE *container;
|
||||
int status;
|
||||
char *mode = SWISSET('r') ? "r" : "r+";
|
||||
|
||||
if (checkDev(words[0]) != 0) {
|
||||
@ -761,6 +767,8 @@ static void doMount(void)
|
||||
struct mountedFS *mount;
|
||||
|
||||
if ((mount = malloc(sizeof(struct mountedFS))) != NULL) {
|
||||
memset(mount, 0, sizeof(struct mountedFS));
|
||||
|
||||
strcpy(mount->name, words[0]);
|
||||
mount->filesys = filesys;
|
||||
mount->blocksz = filesys->blocksz;
|
||||
@ -781,19 +789,21 @@ static void doMount(void)
|
||||
}
|
||||
#endif
|
||||
mount->container = container;
|
||||
mount->skip = 0;
|
||||
|
||||
/*
|
||||
* Verify that the container holds a valid file system
|
||||
*/
|
||||
if ((*filesys->mount)(mount) != 0) {
|
||||
if ((status = (*filesys->mount)(mount)) > 0) {
|
||||
mount->next = mounts;
|
||||
mounts = mount;
|
||||
return;
|
||||
}
|
||||
free(mount);
|
||||
fprintf(stderr,
|
||||
"mount: \"%s\" does not contain a valid file system\n",
|
||||
words[1]);
|
||||
if (status == 0)
|
||||
fprintf(stderr,
|
||||
"mount: \"%s\" does not contain a valid file system\n",
|
||||
words[1]);
|
||||
} else fprintf(stderr, "mount: out of memory\n");
|
||||
fclose(container);
|
||||
} else fprintf(stderr, "mount: failed to open \"%s\"\n", words[1]);
|
||||
@ -892,7 +902,9 @@ static void doNewfs(void)
|
||||
size = (*filesys->size)();
|
||||
|
||||
if ((mount.container = fopen(words[0], "w+")) != NULL) {
|
||||
off_t offset = filesys->blocksz * (size - 1);
|
||||
off_t offset = size - 1;
|
||||
|
||||
mount.skip = 0;
|
||||
|
||||
/*
|
||||
* If an empty file is valid, we are all done
|
||||
@ -900,8 +912,8 @@ static void doNewfs(void)
|
||||
if ((filesys->flags & FS_EMPTYFILE) != 0)
|
||||
return;
|
||||
|
||||
if ((fseeko(mount.container, offset, SEEK_SET) == 0) &&
|
||||
(fwrite(&ch, 1, filesys->blocksz, mount.container) == filesys->blocksz)) {
|
||||
if ((fseeko(mount.container, offset + mount.skip, SEEK_SET) == 0) &&
|
||||
(fwrite(&ch, 1, 1, mount.container) == 1)) {
|
||||
mount.filesys = filesys;
|
||||
mount.blocksz = filesys->blocksz;
|
||||
|
||||
@ -1263,8 +1275,8 @@ static void doType(void)
|
||||
* Close the file
|
||||
*/
|
||||
(*mount->filesys->closeFile)(file);
|
||||
}
|
||||
} else fprintf(stderr, "dump: \"%s\" no such file\n", fname);
|
||||
} else fprintf(stderr, "type: \"%s\" no such file\n", fname);
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
@ -1415,10 +1427,12 @@ static void doHelp(void)
|
||||
"A common command format is used:\n\n"
|
||||
" verb [switches] arg1 arg2 ...\n\n"
|
||||
"The following commands are supported:\n\n"
|
||||
" mount [-r] dev[:] container fstype\n\n"
|
||||
" mount [-r] [-t type] dev[:] container fstype\n\n"
|
||||
"The file system container file is made available to fsio (via the dev\n"
|
||||
"specifier). fstype specifies the type of the container file system.\n"
|
||||
"If -r is specified, the file system will be read-only.\n\n"
|
||||
"If -r is specified, the file system will be read-only.\n"
|
||||
"In some cases (e.g. OS/8) fsio is unable to determine the type of the\n"
|
||||
"underlying disk so it must be specified using \"-t type\"\n\n"
|
||||
" umount dev[:]\n\n"
|
||||
"Remove all knowledge of the container file from fsio.\n\n"
|
||||
" newfs [-t type] container fstype\n\n"
|
||||
@ -1942,7 +1956,7 @@ int FSioReadBlock(
|
||||
{
|
||||
off_t offset = block * mount->blocksz;
|
||||
|
||||
if (fseeko(mount->container, offset, SEEK_SET) == 0)
|
||||
if (fseeko(mount->container, offset + mount->skip, SEEK_SET) == 0)
|
||||
return fread(buf, mount->blocksz, 1, mount->container);
|
||||
|
||||
return 0;
|
||||
@ -1976,8 +1990,87 @@ int FSioWriteBlock(
|
||||
{
|
||||
off_t offset = block * mount->blocksz;
|
||||
|
||||
if (fseeko(mount->container, offset, SEEK_SET) == 0)
|
||||
if (fseeko(mount->container, offset + mount->skip, SEEK_SET) == 0)
|
||||
return fwrite(buf, mount->blocksz, 1, mount->container);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*++
|
||||
* F S i o R e a d S e c t o r
|
||||
*
|
||||
* Read a sector of a specified size from the container. The caller is
|
||||
* responsible for making sure that the buffer has sufficient space for
|
||||
* the sector. This routine is used when file system blocks are constructed
|
||||
* from a number of sectors which are interleaved on the physical disk (e.g.
|
||||
* RX02 floppies).
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* mount - pointer to a mounted file system descriptor
|
||||
* sector - logical sector # in the range 0 - N
|
||||
* size - size of each sector (in bytes)
|
||||
* buf - pointer to the buffer to receive the data
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* The buffer will be overwritten by the contents of the sector from
|
||||
* the container file system
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 1 if read was successful, 0 otherwise
|
||||
*
|
||||
--*/
|
||||
int FSioReadSector(
|
||||
struct mountedFS *mount,
|
||||
unsigned int sector,
|
||||
unsigned int size,
|
||||
void *buf
|
||||
)
|
||||
{
|
||||
off_t offset = sector * size;
|
||||
|
||||
if (fseeko(mount->container, offset + mount->skip, SEEK_SET) == 0)
|
||||
return fread(buf, size, 1, mount->container);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*++
|
||||
* F S i o W r i t e S e c t o r
|
||||
*
|
||||
* Write a sector of a specified size to the container. This routine is used
|
||||
* when file system blocks are constructed from a number of sectors which are
|
||||
* interleaved on the physical disk (e.g. RX02 floppies).
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* mount - pointer to a mounted file system descriptor
|
||||
* sector - logical sector # in the range 0 - N
|
||||
* size - size of each sector (in bytes)
|
||||
* buf - pointer to the buffer to receive the data
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* None
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 1 if read was successful, 0 otherwise
|
||||
*
|
||||
--*/
|
||||
int FSioWriteSector(
|
||||
struct mountedFS *mount,
|
||||
unsigned int sector,
|
||||
unsigned int size,
|
||||
void *buf
|
||||
)
|
||||
{
|
||||
off_t offset = sector * size;
|
||||
|
||||
if (fseeko(mount->container, offset + mount->skip, SEEK_SET) == 0)
|
||||
return fwrite(buf, size, 1, mount->container);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ enum openMode { M_RD, M_WR };
|
||||
#include "dos11.h"
|
||||
#include "rt11.h"
|
||||
#include "dosmt.h"
|
||||
#include "os8.h"
|
||||
|
||||
/*
|
||||
* All of the supported file systems are natively little endian so we only
|
||||
@ -150,17 +151,22 @@ struct mountedFS {
|
||||
/* Bits after 0x0080 reserved for */
|
||||
/* file system use */
|
||||
FILE *container; /* Container file access */
|
||||
off_t skip; /* Data to skip in container file */
|
||||
union {
|
||||
struct DOS11data _dos11;
|
||||
struct RT11data _rt11;
|
||||
struct DOSMTdata _dosmt;
|
||||
struct OS8data _os8;
|
||||
} FSdata;
|
||||
#define dos11data FSdata._dos11
|
||||
#define rt11data FSdata._rt11
|
||||
#define dosmtdata FSdata._dosmt
|
||||
#define os8data FSdata._os8
|
||||
};
|
||||
|
||||
extern int FSioReadBlock(struct mountedFS *, unsigned int, void *);
|
||||
extern int FSioWriteBlock(struct mountedFS *, unsigned int, void *);
|
||||
extern int FSioReadSector(struct mountedFS *, unsigned int, unsigned int, void *);
|
||||
extern int FSioWriteSector(struct mountedFS *, unsigned int, unsigned int, void *);
|
||||
|
||||
#endif
|
||||
|
||||
@ -87,7 +87,7 @@ Full command syntax:
|
||||
|
||||
1. mount
|
||||
|
||||
mount [-dfr] dev[:] container type
|
||||
mount [-dfr] [-t type] dev[:] container type
|
||||
|
||||
Make the specified container file available to fsio for I/O.
|
||||
|
||||
@ -97,6 +97,10 @@ Full command syntax:
|
||||
validate the container file format
|
||||
-r If present, the file system is only available for read access
|
||||
|
||||
-t type Specify the type of the container file. This is only required
|
||||
for OS/8 file systems where type should be one of "rx01",
|
||||
"rx02" or "rk05".
|
||||
|
||||
dev[:] User supplied name to be used for accessing files within the
|
||||
container file. Files within the container are named by using
|
||||
the syntax dev:filespec where filespec uses the native syntax
|
||||
@ -133,6 +137,7 @@ Full command syntax:
|
||||
dos11 RK05 image (2.5MB, 4800 blocks)
|
||||
rt11 MSCP image (32MB, 65535 blocks)
|
||||
dosmt An empty file suitable for use with any magtape controller
|
||||
os8 An OS/8 file system
|
||||
|
||||
-t type Use a different size for the container file. The size used
|
||||
will be file system dependent.
|
||||
@ -142,6 +147,12 @@ Full command syntax:
|
||||
rl02 RL02 image (10MB, 20480 blocks)
|
||||
rx20 RX20 image (512KB, 1024 blocks)
|
||||
|
||||
For os8, the following disk types are valid:
|
||||
|
||||
rk05 RK05 image (3248 blocks)
|
||||
rx01 RX01 image (2002 sectors of 128 bytes each)
|
||||
rx02 RX02 imgae (2002 sectors of 256 bytes each)
|
||||
|
||||
container The name of the file to create
|
||||
|
||||
type The type of the file system to create in the container
|
||||
|
||||
@ -274,14 +274,44 @@ before you have any network running.
|
||||
|
||||
TOPS-10
|
||||
-------
|
||||
The RTFLX utility is available on TOPS-10 reading/writing files on an RX20
|
||||
drive (combination of RX02 drive and controller) attached to a DECsystem-2020
|
||||
(KS10). In order to access the RX20, a new system generation must be
|
||||
performed. There is a help file on Tops-10 for RTFLX but no other
|
||||
documentation.
|
||||
|
||||
Use the RTFLX utility to copy the file over to the TOPS-10 file system. When
|
||||
creating the SIMH file using the "newfs" command use the "-t rx20" switch to
|
||||
create a floppy image. The RX20 is a double density floppy and is only
|
||||
available on KS10 systems.
|
||||
.
|
||||
Simulation stopped, PC: 000001 (SOJG 6,1)
|
||||
sim> att ry0 xfer.dsk
|
||||
RY: buffering file in memory
|
||||
sim> c
|
||||
|
||||
There is a help file on Tops-10 for RTFLX but no other documentation. The
|
||||
default TOPS-10 monitor does not include support for the RX20 so a new
|
||||
system generation will be required.
|
||||
.assign rxa0: rt:
|
||||
RXA000 assigned
|
||||
.r rtflx
|
||||
|
||||
|
||||
RTFLX>dir
|
||||
|
||||
FILE TXT 1 11-Jun-87
|
||||
|
||||
Total of 1 block in 1 file
|
||||
973 blocks free on RT:
|
||||
|
||||
RTFLX>copy rt:file.txt
|
||||
FILE.TXT=RT:FILE.TXT
|
||||
|
||||
RTFLX>exit
|
||||
|
||||
.dir *.txt
|
||||
|
||||
|
||||
FILE TXT 1 <057> 11-Jun-87 DSKB: [1,2]
|
||||
|
||||
.deassign rxa0:
|
||||
.
|
||||
|
||||
If you use the RTFLX "ZERO" command to initialize an RT-11 file system it
|
||||
will create an RT-11 V2 format file system and you will need to use the "-f"
|
||||
switch to force fsio to see the file system.
|
||||
|
||||
I do not currently have a functioning TOPS-10 system to test this on.
|
||||
|
||||
3015
converters/fsio/os8.c
Normal file
3015
converters/fsio/os8.c
Normal file
File diff suppressed because it is too large
Load Diff
248
converters/fsio/os8.h
Normal file
248
converters/fsio/os8.h
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2019 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN FORECAST "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OS8_H__
|
||||
#define __OS8_H__
|
||||
|
||||
/*
|
||||
* General disk layout (each block is 256 12-bit words).
|
||||
*
|
||||
* Block
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 0 | Reserved |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 1-6 | Directory segments |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 7-12 | Keyboard Monitor | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 13-15 | User Service Routine | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 16-25 | Device Handlers | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 26 | Enter Processor For USR | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 27-50 | System Scratch Blocks | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 51-53 | Command Decoder | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 54-55 | SAVE And DATE Overlays | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 56 | Monitor Error Routine | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 57 | CHAIN Processor For USR | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 60-63 | System ODT | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 64 | Reserved For System Expansion | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 65 | CCL Reminiscences | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 66 | 12K TD8E Resident Code | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 67 | CCL Overlay | **
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* Files | ... |
|
||||
* | ... |
|
||||
* | ... |
|
||||
* | ... |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* End Of Volume
|
||||
*
|
||||
* Blocks marked "**" are only reserved on System Devices, on non-System
|
||||
* Devices, file storage starts at block 7.
|
||||
*
|
||||
* Directory Segment Header:
|
||||
*
|
||||
* Word
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 0 | Minus # of entries in this segment |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 1 | Starting block # of first file in this segment|
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 2 | Link to next directory segment |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 3 | Flag Word |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 4 | Minus # of additional information words |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Directory Entry:
|
||||
*
|
||||
* Word
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 0 | Sixbit ASCII File Name (chars 1 - 2) |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 1 | Sixbit ASCII File Name (chars 3 - 4) |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 2 | Sixbit ASCII File Name (chars 5 - 6) |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 3 | Sixbit ASCII File Extension (chars 1 - 2) |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | N additional information words |
|
||||
* | ... |
|
||||
* | ... |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* N + 4 | Minus file length in blocks |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* If there are additional informations words in the directory, the file
|
||||
* creation time is stored in word 4 (zero means not available):
|
||||
*
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | | | |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | | | | | |
|
||||
* | | | | +-------+
|
||||
* | | +---------------+ |
|
||||
* +-----------+ | Year - 1970
|
||||
* | Day of Month (1 - 31)
|
||||
* Month (1 - 12)
|
||||
*/
|
||||
|
||||
#define OS8_BLOCKSIZE 256 /* Size of a block on disk (words) */
|
||||
|
||||
#define OS8_DSSTART 1 /* Start of directory segments */
|
||||
#define OS8_DSLAST 6 /* Last directory segment */
|
||||
#define OS8_DATA 7 /* Start of data (non-system device) */
|
||||
|
||||
#define OS8_DH_ENTRIES 0 /* -(# of entries in segment) */
|
||||
#define OS8_DH_START 1 /* Block # for segment start */
|
||||
#define OS8_DH_NEXT 2 /* Next directory segment */
|
||||
#define OS8_DH_FLAGWD 3 /* Flag word */
|
||||
#define OS8_DH_EXTRA 4 /* -(# of additional info. words) */
|
||||
#define OS8_DH_SIZE 5 /* Size of directory header */
|
||||
|
||||
#define OS8_DI_FNAME1 0 /* File name (chars 1 - 2) */
|
||||
#define OS8_DI_FNAME2 1 /* File name (chars 3 - 4) */
|
||||
#define OS8_DI_FNAME3 2 /* File name (chars 5 - 6) */
|
||||
#define OS8_DI_EXT 3 /* File extension (1 - 2 chars) */
|
||||
/* Additional words go here */
|
||||
#define OS8_DI_DATE 4 /* Optional creation date */
|
||||
#define OS8_DI_LENGTH 4 /* -(File length in blocks) */
|
||||
#define OS8_DI_SIZE 5 /* Default entry size */
|
||||
|
||||
#define OS8_ED_IND 0 /* Empty directory entry */
|
||||
#define OS8_ED_LENGTH 1 /* -(Empty file length in blocks) */
|
||||
#define OS8_ED_SIZE 2 /* Entry size */
|
||||
|
||||
/*
|
||||
* Device specific definitions
|
||||
*/
|
||||
#define OS8_RK05FS_BLKS 3248 /* Blocks in an RK05 file system */
|
||||
|
||||
#define OS8_RX01SS 128 /* Byte sector size of RX01 floppy */
|
||||
#define OS8_RX02SS 256 /* Byte sector size of RX02 floppy */
|
||||
#define OS8_RX01SS_W 64 /* Word sector size of RX01 floppy */
|
||||
#define OS8_RX02SS_W 128 /* Word sector size of RX02 floppy */
|
||||
#define OS8_RX0xNSECT 26 /* Sectors/track on RX01/RX02 */
|
||||
#define OS8_RX0xSZ 2002 /* Sectors on an RX01/RX02 */
|
||||
|
||||
/*
|
||||
* Structure to describe a filename. Asterisks may be used as wild card
|
||||
* characters for the 2 components of a filename; namd and extension
|
||||
*/
|
||||
struct os8FileSpec {
|
||||
uint8_t flags; /* Wild card indicators */
|
||||
uint16_t name[3]; /* File name (sixbit) */
|
||||
uint16_t ext; /* File extension (sixbit) */
|
||||
char fname[6]; /* File name (ASCII) */
|
||||
char fext[2]; /* File extension (ASCII) */
|
||||
};
|
||||
#define OS8_WC_NAME 001 /* Wild card in name */
|
||||
#define OS8_WC_EXT 002 /* Wild card in extension */
|
||||
|
||||
#define OS8_M_NONE 0000 /* Wild cards not allowed */
|
||||
#define OS8_M_ALLOW 0001 /* Wild cards allowed */
|
||||
#define OS8_M_NONAME 0002 /* Wild cards allowed */
|
||||
/* If no filename + extension */
|
||||
/* present, default to *.* */
|
||||
/*
|
||||
* OS/8 files pack 3 bytes into a pair of 12-bit words. The following states
|
||||
* are used to pack/unpack bytes.
|
||||
*/
|
||||
#define OS8_BYTE0 0 /* Pack/unpack byte 0 */
|
||||
#define OS8_BYTE1 1 /* Pack/unpack byte 1 */
|
||||
#define OS8_BYTE2 2 /* Pack/unpack byte 2 */
|
||||
#define OS8_CHECK 3 /* Check for end of block/EOF */
|
||||
|
||||
/*
|
||||
* Structure to define an open file. This is an OS/8 directory entry along
|
||||
* with sufficient information to be able to write the directory entry back
|
||||
* to disk.
|
||||
*/
|
||||
struct os8OpenFile {
|
||||
uint16_t name[3]; /* File name */
|
||||
uint16_t ext; /* File extension */
|
||||
uint16_t creation; /* Creation date */
|
||||
uint16_t length; /* File length (blocks) */
|
||||
/* End of directory entry */
|
||||
uint8_t segment; /* Directory segment */
|
||||
uint16_t offset; /* Directory offset */
|
||||
uint16_t entrysz; /* Size of directory entries */
|
||||
uint16_t extra; /* Extra words in directory entries */
|
||||
uint16_t remain; /* Remaining directory entries */
|
||||
/* Start of read/write info */
|
||||
enum openMode mode; /* Open mode (read/write) */
|
||||
struct mountedFS *mount; /* Mounted file system descriptor */
|
||||
uint8_t unit; /* File system # */
|
||||
uint16_t *buffer; /* Private buffer for file I/O */
|
||||
uint16_t start; /* Starting block # */
|
||||
uint16_t current; /* Current block # */
|
||||
uint16_t last; /* Last block # */
|
||||
uint16_t wordpos; /* Current word offset */
|
||||
uint8_t bytepos; /* Current byte position */
|
||||
off_t written; /* # of bytes written to the file */
|
||||
};
|
||||
|
||||
/*
|
||||
* Device descriptor
|
||||
*/
|
||||
struct OS8device {
|
||||
char *name; /* Device name */
|
||||
uint8_t filesys; /* # of file systems on device */
|
||||
size_t diskSize; /* # of blocks on device */
|
||||
off_t skip; /* Reserved space at start of disk */
|
||||
uint16_t blocks[8]; /* File system sizes */
|
||||
int (*blockPresent)(struct mountedFS *, uint8_t, unsigned int);
|
||||
int (*readBlock)(struct mountedFS *, uint8_t, unsigned int, void *);
|
||||
int (*writeBlock)(struct mountedFS *, uint8_t, unsigned int, void *);
|
||||
};
|
||||
|
||||
/*
|
||||
* OS/8 specific data area
|
||||
*/
|
||||
struct OS8data {
|
||||
unsigned int blocks; /* Size of container */
|
||||
struct OS8device *device; /* Device type */
|
||||
uint8_t devices; /* # of "devices" present */
|
||||
uint8_t valid; /* Bitmap of valid devices */
|
||||
uint16_t date; /* Date for creating files */
|
||||
uint16_t buf[OS8_BLOCKSIZE]; /* Disk buffer */
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -45,8 +45,9 @@ static struct DiskSize {
|
||||
char *name; /* Disk name */
|
||||
size_t size; /* Disk size */
|
||||
} rt11DiskSize[] = {
|
||||
{ "rl02", RT11_RL02SZ },
|
||||
{ "rx20", RT11_RX20SZ },
|
||||
{ "rl02", RT11_RL02SZ * RT11_BLOCKSIZE },
|
||||
{ "rx01", RT11_RX0xSZ * RT11_RX01SS },
|
||||
{ "rx02", RT11_RX0xSZ * RT11_RX02SS },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
@ -337,6 +338,39 @@ int rt11MatchRegex(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*++
|
||||
* M a p L o g T o P h y s
|
||||
*
|
||||
* Map a logical sector address to a physical sector address for an RX01/RX02
|
||||
* drive.
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* sectno - logical sector number
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* None
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Physical sector number
|
||||
*
|
||||
--*/
|
||||
unsigned int MapLogToPhys(
|
||||
unsigned int sectno
|
||||
)
|
||||
{
|
||||
unsigned int i, track, sector;
|
||||
|
||||
track = sectno / RT11_RX0xNSECT;
|
||||
i = (sectno % RT11_RX0xNSECT) << 1;
|
||||
if (i >= RT11_RX0xNSECT)
|
||||
i++;
|
||||
sector = (i + (6 * track)) % RT11_RX0xNSECT;
|
||||
return sector + (track * RT11_RX0xNSECT);
|
||||
}
|
||||
|
||||
/*++
|
||||
* r t 1 1 R e a d B l o c k
|
||||
*
|
||||
@ -367,10 +401,10 @@ int rt11ReadBlock(
|
||||
)
|
||||
{
|
||||
struct RT11data *data = &mount->rt11data;
|
||||
void *buffer = buf == NULL ? data->buf : buf;
|
||||
char *buffer = buf == NULL ? data->buf : buf;
|
||||
int status = 0;
|
||||
|
||||
if (PARTITIONVALID(data, unit)) {
|
||||
if (RT11_PARTITIONVALID(data, unit)) {
|
||||
if (block > data->maxblk[unit]) {
|
||||
ERROR("Attempt to read block (%u) outside file system \"%s%o:\"\n",
|
||||
block, mount->name, unit);
|
||||
@ -383,7 +417,25 @@ int rt11ReadBlock(
|
||||
mount->name, unit, block);
|
||||
#endif
|
||||
|
||||
status = FSioReadBlock(mount, (unit << 16) | block, buffer);
|
||||
if (data->sectorsz != 0) {
|
||||
/*
|
||||
* The sectors making up the disk are sector-interleaved. The algorithm
|
||||
* below is for RX01/RX02 interleave. Note that all such devices are
|
||||
* small enough that there can only be a single file system present.
|
||||
*/
|
||||
unsigned int count = RT11_BLOCKSIZE / data->sectorsz;
|
||||
unsigned int sectno = block * count;
|
||||
|
||||
do {
|
||||
unsigned int sector = MapLogToPhys(sectno);
|
||||
|
||||
status = FSioReadSector(mount, sector, data->sectorsz, buffer);
|
||||
|
||||
count--;
|
||||
buffer += data->sectorsz;
|
||||
sectno++;
|
||||
} while ((count != 0) && (status != 0));
|
||||
} else status = FSioReadBlock(mount, (unit << 16) | block, buffer);
|
||||
|
||||
if (status == 0)
|
||||
ERROR("I/O error on \"%s%o:\"\n", mount->name, unit);
|
||||
@ -422,10 +474,10 @@ int rt11WriteBlock(
|
||||
)
|
||||
{
|
||||
struct RT11data *data = &mount->rt11data;
|
||||
void *buffer = buf == NULL ? data->buf : buf;
|
||||
char *buffer = buf == NULL ? data->buf : buf;
|
||||
int status = 0;
|
||||
|
||||
if (PARTITIONVALID(data, unit)) {
|
||||
if (RT11_PARTITIONVALID(data, unit)) {
|
||||
if (block > data->maxblk[unit]) {
|
||||
ERROR("Attempt to write block (%u) outside file system \"%s%o:\"\n",
|
||||
block, mount->name, unit);
|
||||
@ -438,7 +490,25 @@ int rt11WriteBlock(
|
||||
mount->name, unit, block);
|
||||
#endif
|
||||
|
||||
status = FSioWriteBlock(mount, (unit << 16) | block, buffer);
|
||||
if (data->sectorsz != 0) {
|
||||
/*
|
||||
* The sectors making up the disk are sector-interleaved. The algorithm
|
||||
* below is for RX01/RX02 interleave. Note that all such devices are
|
||||
* small enough that there can only be a single file system present.
|
||||
*/
|
||||
unsigned int count = RT11_BLOCKSIZE / data->sectorsz;
|
||||
unsigned int sectno = block * count;
|
||||
|
||||
do {
|
||||
unsigned int sector = MapLogToPhys(sectno);
|
||||
|
||||
status = FSioWriteSector(mount, sector, data->sectorsz, buffer);
|
||||
|
||||
count--;
|
||||
buffer += data->sectorsz;
|
||||
sectno++;
|
||||
} while ((count != 0) && (status != 0));
|
||||
} else status = FSioWriteBlock(mount, (unit << 16) | block, buffer);
|
||||
|
||||
if (status == 0)
|
||||
ERROR("I/O error on \"%s%o:\"\n", mount->name, unit);
|
||||
@ -450,7 +520,8 @@ int rt11WriteBlock(
|
||||
/*++
|
||||
* r t 1 1 R e a d D i r S e g m e n t
|
||||
*
|
||||
* Read a directory segment (2 disk blocks) into the mount specific buffer.
|
||||
* Read a directory segment (2 file system blocks) into the mount specific
|
||||
* buffer.
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
@ -460,7 +531,7 @@ int rt11WriteBlock(
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* The directory segment will be read into the mount specific buffer.
|
||||
* The directory segment will be read into the mount specific buffer.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
@ -680,7 +751,7 @@ static int rt11BestFit(
|
||||
* r t 1 1 M e r g e E m p t y R e g i o n s
|
||||
*
|
||||
* Following a delete operation, check if we can merge empty regions
|
||||
* together anc compact the directory segment. In the worst case there
|
||||
* together and compact the directory segment. In the worst case there
|
||||
* can be 3 directory entries involved; <UNUSED>, <File>, <UNUSED>. If
|
||||
* <File> is deleted we need to collapse all three <UNUSED> entries to one.
|
||||
* The directory segment is currently in the mount point specific buffer.
|
||||
@ -1131,7 +1202,7 @@ int rt11LookupFile(
|
||||
{
|
||||
struct RT11data *data = &mount->rt11data;
|
||||
|
||||
if (PARTITIONVALID(data, unit)) {
|
||||
if (RT11_PARTITIONVALID(data, unit)) {
|
||||
uint16_t entrysz, position, dsseg = 1;
|
||||
|
||||
do {
|
||||
@ -1684,6 +1755,26 @@ static int rt11Mount(
|
||||
struct RT11data *data = &mount->rt11data;
|
||||
struct stat stat;
|
||||
|
||||
data->sectorsz = 0;
|
||||
|
||||
/*
|
||||
* Check for device type override.
|
||||
*/
|
||||
if (SWISSET('t')) {
|
||||
if (strcmp("rx01", SWGETVAL('t')) == 0) {
|
||||
mount->skip = RT11_RX0xNSECT * RT11_RX01SS;
|
||||
data->sectorsz = RT11_RX01SS;
|
||||
}
|
||||
if (strcmp("rx02", SWGETVAL('t')) == 0) {
|
||||
mount->skip = RT11_RX0xNSECT * RT11_RX02SS;
|
||||
data->sectorsz = RT11_RX02SS;
|
||||
}
|
||||
|
||||
if (data->sectorsz == 0)
|
||||
fprintf(stderr,
|
||||
"mount: Ignoring unknown disk type \"%s\"\n", SWGETVAL('t'));
|
||||
}
|
||||
|
||||
memset(&data->valid, 0, sizeof(data->valid));
|
||||
|
||||
if (fstat(fileno(mount->container), &stat) == 0) {
|
||||
@ -1727,7 +1818,7 @@ static int rt11Mount(
|
||||
mount->name, validcount, validcount == 1 ? "" : "s");
|
||||
|
||||
for (i = 0; (i < 256) && (validcount != 0); i++)
|
||||
if (PARTITIONVALID(data, i)) {
|
||||
if (RT11_PARTITIONVALID(data, i)) {
|
||||
uint16_t entrysz, freeblks = 0, dsseg = 1;
|
||||
uint16_t highest = 0;
|
||||
|
||||
@ -1756,6 +1847,10 @@ static int rt11Mount(
|
||||
|
||||
if (!quiet) {
|
||||
char vers[4], *version = NULL;
|
||||
uint16_t cnt, extra;
|
||||
|
||||
cnt = le16toh(data->buf[RT11_DH_COUNT]);
|
||||
extra = le16toh(data->buf[RT11_DH_EXTRA]);
|
||||
|
||||
if (rt11ReadBlock(mount, i, RT11_HOME, NULL) == 0)
|
||||
return 0;
|
||||
@ -1788,11 +1883,11 @@ static int rt11Mount(
|
||||
printf(" Version: %s, System ID: %12s\n",
|
||||
version, (char *)&data->buf[RT11_HB_SYSID]);
|
||||
printf(" Total blocks: %5d, Free blocks: %5d\n"
|
||||
" Directory segments: %2d (Highest %d)\n"
|
||||
" Directory segments: %2d (Highest in use: %d)\n"
|
||||
" Extra bytes/directory entry: %d\n",
|
||||
data->maxblk[i] + 1, freeblks,
|
||||
le16toh(data->buf[RT11_DH_COUNT]), highest,
|
||||
le16toh(data->buf[RT11_DH_EXTRA]));
|
||||
data->maxblk[i] + 1, freeblks, cnt, highest, extra);
|
||||
if (data->sectorsz != 0)
|
||||
printf(" Sector size: %d\n", data->sectorsz);
|
||||
}
|
||||
validcount--;
|
||||
}
|
||||
@ -1829,7 +1924,7 @@ static void rt11Umount(
|
||||
/*++
|
||||
* r t 1 1 S i z e
|
||||
*
|
||||
* Return the size of and RT-11 container file.
|
||||
* Return the size of an RT-11 container file.
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
@ -1846,7 +1941,7 @@ static void rt11Umount(
|
||||
--*/
|
||||
static size_t rt11Size(void)
|
||||
{
|
||||
size_t size = RT11_MAXPARTSZ - 1;
|
||||
size_t size = (RT11_MAXPARTSZ - 1) * RT11_BLOCKSIZE;
|
||||
|
||||
if (SWISSET('t')) {
|
||||
int i = 0;
|
||||
@ -1859,7 +1954,7 @@ static size_t rt11Size(void)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (size == (RT11_MAXPARTSZ - 1))
|
||||
if (size == ((RT11_MAXPARTSZ - 1) * RT11_BLOCKSIZE))
|
||||
fprintf(stderr,
|
||||
"newfs: Invalid device type \"%s\", using default\n", type);
|
||||
}
|
||||
@ -1893,7 +1988,43 @@ static int rt11Newfs(
|
||||
{
|
||||
struct RT11data *data = &mount->rt11data;
|
||||
int i;
|
||||
uint16_t checksum = 0;
|
||||
uint16_t checksum = 0, extra = 0;;
|
||||
|
||||
/*
|
||||
* Check for device type override.
|
||||
*/
|
||||
if (SWISSET('t')) {
|
||||
if (strcmp("rx01", SWGETVAL('t')) == 0) {
|
||||
mount->skip = RT11_RX0xNSECT * RT11_RX01SS;
|
||||
data->sectorsz = RT11_RX01SS;
|
||||
}
|
||||
if (strcmp("rx02", SWGETVAL('t')) == 0) {
|
||||
mount->skip = RT11_RX0xNSECT * RT11_RX02SS;
|
||||
data->sectorsz = RT11_RX02SS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for extra bytes on each directory entry, rounded up to nearest
|
||||
* even value.
|
||||
*/
|
||||
if (SWISSET('e')) {
|
||||
char *endptr;
|
||||
|
||||
extra = strtoul(SWGETVAL('e'), &endptr, 10);
|
||||
extra = (extra + 1) & ~1;
|
||||
|
||||
if ((extra > 63) || (*endptr != '\0')) {
|
||||
fprintf(stderr, "newfs: bad -e switch value \"%s\" - ignored\n",
|
||||
SWGETVAL('e'));
|
||||
extra = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove possible first track
|
||||
*/
|
||||
size = ((size * RT11_BLOCKSIZE) - mount->skip) / RT11_BLOCKSIZE;
|
||||
|
||||
/*
|
||||
* Mark partition 0 as valid
|
||||
@ -1901,6 +2032,7 @@ static int rt11Newfs(
|
||||
memset(data->valid, 0, sizeof(data->valid));
|
||||
data->valid[0] = 1;
|
||||
data->maxblk[0] = size;
|
||||
data->first[0] = RT11_DSSTART;
|
||||
data->filesystems = 1;
|
||||
|
||||
/*
|
||||
@ -1931,6 +2063,7 @@ static int rt11Newfs(
|
||||
|
||||
data->buf[RT11_DH_COUNT] = htole16(RT11_DS_MAX);
|
||||
data->buf[RT11_DH_HIGHEST] = htole16(1);
|
||||
data->buf[RT11_DH_EXTRA] = htole16(extra);
|
||||
data->buf[RT11_DH_START] = htole16(RT11_DSSTART + (2 * RT11_DS_MAX));
|
||||
|
||||
if (i == 1) {
|
||||
@ -1977,7 +2110,7 @@ static void rt11Info(
|
||||
struct RT11data *data = &mount->rt11data;
|
||||
|
||||
if (present) {
|
||||
if (PARTITIONVALID(data, unit))
|
||||
if (RT11_PARTITIONVALID(data, unit))
|
||||
info(mount, unit);
|
||||
} else {
|
||||
uint16_t i, count = data->filesystems;
|
||||
@ -1986,7 +2119,7 @@ static void rt11Info(
|
||||
* Display information about all valid partitions
|
||||
*/
|
||||
for (i = 0; (i < 256) && (count != 0); i++)
|
||||
if (PARTITIONVALID(data, i)) {
|
||||
if (RT11_PARTITIONVALID(data, i)) {
|
||||
info(mount, i);
|
||||
count--;
|
||||
}
|
||||
@ -2027,7 +2160,7 @@ static void rt11Dir(
|
||||
return;
|
||||
}
|
||||
|
||||
if (PARTITIONVALID(data, unit)) {
|
||||
if (RT11_PARTITIONVALID(data, unit)) {
|
||||
uint16_t entrysz, dsseg = 1;
|
||||
regex_t reg;
|
||||
|
||||
@ -2404,7 +2537,7 @@ static size_t rt11ReadFile(
|
||||
* # of bytes of data written, 0 means EOF or error
|
||||
*
|
||||
--*/
|
||||
size_t rt11WriteFile(
|
||||
static size_t rt11WriteFile(
|
||||
void *filep,
|
||||
void *buf,
|
||||
size_t buflen
|
||||
|
||||
@ -166,6 +166,9 @@
|
||||
#define RT11_HOME 1 /* Home block is always 1 */
|
||||
#define RT11_DSSTART 6 /* Start of directory segs */
|
||||
#define RT11_BLOCKSIZE 512 /* Size of a data block on disk */
|
||||
#define RT11_RX01SS 128 /* Sector size of RX01 floppy */
|
||||
#define RT11_RX02SS 256 /* Sector size of RX02 floppy */
|
||||
#define RT11_RX0xNSECT 26 /* Sectors/track on RX01/RX02 */
|
||||
|
||||
#define RT11_SYSVER_V3A 36521
|
||||
#define RT11_SYSVER_V04 36434
|
||||
@ -181,15 +184,15 @@
|
||||
#define RT11_VMSSYSID "DECVMSEXCHNG" /* VMS exchange created volume */
|
||||
|
||||
/*
|
||||
* Partition sizes. The last block os a maximum sized partition is unused.
|
||||
* The minimum size is based on a file system having 1 directory segment and
|
||||
* 1 data block! Is this reasonable?
|
||||
* Partition sizes. The last block of a maximum sized partition (32MB) is
|
||||
* unused. The minimum size is based on a file system having 1 directory
|
||||
* segment and 1 data block! Is this reasonable?
|
||||
*/
|
||||
#define RT11_MAXPARTSZ 0200000 /* Max partition size */
|
||||
#define RT11_MINPARTSZ 0000010 /* Min partition size */
|
||||
|
||||
#define RT11_RL02SZ 20480 /* Size of an RL02 drive */
|
||||
#define RT11_RX20SZ 1024 /* Size of an RX20 floppy drive */
|
||||
#define RT11_RL02SZ 20480 /* Blocks on an RL02 drive */
|
||||
#define RT11_RX0xSZ 2002 /* Sectors on an RX01/RX02 */
|
||||
|
||||
#define RT11_HB_BBLOCK 0000 /* Bad block replacement tbl */
|
||||
#define RT11_HB_RESTORE 0102 /* INIT/RESTORE data area */
|
||||
@ -287,6 +290,8 @@ struct rt11OpenFile {
|
||||
*/
|
||||
struct RT11data {
|
||||
unsigned int blocks; /* Size of container */
|
||||
unsigned int sectorsz; /* Interleave sector size */
|
||||
/* 0 if no interleave */
|
||||
uint16_t filesystems; /* Max # of filesystems */
|
||||
uint16_t valid[16]; /* Valid partitions */
|
||||
uint16_t maxblk[256]; /* Max block address */
|
||||
@ -294,6 +299,6 @@ struct RT11data {
|
||||
uint16_t buf[512]; /* Disk buffer - enough for a */
|
||||
/* directory segment */
|
||||
};
|
||||
#define PARTITIONVALID(d, u) ((d->valid[u / 16] & (1 << (u % 16))) != 0)
|
||||
#define RT11_PARTITIONVALID(d, u) ((d->valid[u / 16] & (1 << (u % 16))) != 0)
|
||||
|
||||
#endif
|
||||
|
||||
20
extracters/ods2/Makefile
Normal file
20
extracters/ods2/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
# all of these can be over-ridden on the "make" command line if they don't suit your environment.
|
||||
TOOL=ods2
|
||||
CFLAGS=-O2 -Wall -Wshadow -Wextra -pedantic -Woverflow -Wstrict-overflow
|
||||
BIN=/usr/local/bin
|
||||
INSTALL=install
|
||||
CC=gcc
|
||||
|
||||
$(TOOL): $(TOOL).c access.c cache.c device.c direct.c phynt.c rms.c vmstime.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $(TOOL) $(TOOL).c access.c cache.c device.c direct.c phynt.c rms.c vmstime.c $(LDLIBS)
|
||||
|
||||
.PHONY: clean install uninstall
|
||||
|
||||
clean:
|
||||
rm -f $(TOOL)
|
||||
|
||||
install: $(TOOL)
|
||||
$(INSTALL) -p -m u=rx,g=rx,o=rx $(TOOL) $(BIN)
|
||||
|
||||
uninstall:
|
||||
rm -f $(BIN)/$(TOOL)
|
||||
Loading…
x
Reference in New Issue
Block a user