[comp.sources.amiga] v90i213: MSH 1.30 - Messydos File System Handler, Part01/06

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (07/16/90)

Submitted-by: Olaf 'Rhialto' Seibert <U211344%HNYKUN11.BITNET@CUNYVM.CUNY.EDU>
Posting-number: Volume 90, Issue 213
Archive-name: devices/msh-1.30/part01

[ In this case, version number 1.30 is newer than 1.5  ...tad ]
[ see comp.binaries.amiga for executables  ...tad ]
[ the manual pages have been uuencoded to preserve special characters ]

Msh		An Amiga file system handler that handles MSDOS formatted
		diskettes.  Version "1.30" (Release 1 patch 3).  You can
		use files on such disks in almost exactly the same way as
		you use files on native AmigaDOS disks.  This is a fully
		functional, read/write version, that supports 8, 9, or 10
		sector disks of 80 tracks, and should also work on 40 track
		drives and hard disks with 12 or 16 bit FAT of any
		dimension the FAT allows.  Update to version "1.5" (Release
		1) on disk 327.  Includes source.
		Author:  Olaf Seibert


#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 6)."
# Contents:  doc doc/RELEASE-NOTES doc/rx50notes src src/Makefile
#   src/date.c src/dev.h src/device.h src/die.c src/dos.h src/han.h
#   src/hancmd.c src/hanreq.c src/ignore.c src/messyfmt.c
#   src/support.c
# Wrapped by tadguy@xanth on Sun Jul 15 19:59:03 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'doc' ; then
    echo shar: Creating directory \"'doc'\"
    mkdir 'doc'
fi
if test -f 'doc/RELEASE-NOTES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/RELEASE-NOTES'\"
else
echo shar: Extracting \"'doc/RELEASE-NOTES'\" \(5192 characters\)
sed "s/^X//" >'doc/RELEASE-NOTES' <<'END_OF_FILE'
X
X        M E S S Y D O S   F I L E   S Y S T E M   H A N D L E R
X        -------------------------------------------------------
X        by Olaf 'Rhialto' Seibert                   05-Jun-1990
X
X*******************************************************************************
X    MSH is (C) Copyright 1989,1990 by Olaf Seibert. All rights reserved.
X    Freely distributable, except that it may not be distributed for profit
X    without permission from the author. Hereby, Fred Fish explicitly gets
X    permission to include MSH in his library of freely distributable Amiga
X    software.
X*******************************************************************************
X
X    This is patch #3 to MSH release #1.
X
XBug fixed:
X    - device: The IBM disk format seems to have an index mark $5224/$5552
X      before the first sector, even though the machines I tested it with
X      did not seem to miss it.
X
XInconvenience removed:
X    - MSH: no longer produces read error requestors when the bootblock of a
X      newly inserted disk cannot be read. The disk is silently ignored.
X
XFeature added:
X    - MSH: is now more polite to some DFx: that uses the same physical
X      drive.
X
XMisc:
X    - Reduced stack size of messydisk.device task (2K -> 1K) and of the
X      filesystem itself (4K -> 3K). Xoper shows that (most of the time)
X      no more than half of these stacks seems to be used.
X
XReminder:
X    If you like the program, feel free to send me some $$, or even $$$ if
X    you feel like it. All shareware resellers (and especially those in
X    Germany) are reminded that they are NOT allowed to make any profit off
X    my work. Resellers are considered to make an illegal profit if they
X    charge more for a disk than Fred Fish does. Those resellers do NOT have
X    a licence to use or copy MSH. Also, if you distribute MSH:, you must
X    distribute it in its entirety: you are not allowed to leave parts out.
X
X====05-May-1990=====About patch #2a-2c=========================================
X
XThere have been many 'patch 2' versions. Therefore, I bumped the
Xversion number after I cleaned up the distribution, so that a consistent
Xversion number is possible.
X
X====11-Mar-1990=====From patch #1==============================================
X
X    This is patch #1 to MSH release #1. It consists of all binaries and
Xdocumentation. There are replacement source files, and a patch file for the
Xothers.
X
XBugs fixed:
X    - device: I/O could be done during CloseDevice(). Trackdisk does not
X      seem to do this, and was implemented incorrectly anyhow.
X    - handler: Examine() of the root directory got a . afther the 8th
X      character of the volume name
X
XInconvenience removed:
X    - handler: The AmigaDOS 1.3 List and Dir commands thought that all
X      files were directories.
X
XFeatures added:
X    - handler: Now uses the Reserved entry in the Mountlist. You should
X      normally set this to 0.
X    - MSH::F+ and MSH::F-.
X    - messyfmt: You can now write just the bootblock. The disk must
X      already be formatted.
X    - device: you can now, with some care, format disks with less than 8
X      sectors per track.
X
X====11-Feb-1990=====From release #1============================================
X
X    This is the first really public release of the MessyFileSystem, or MSH
Xfor short. It has circulated among a small audience, and I entered it in a
Xprogramming contest held by the German 'Amiga-Magazin'. They were too dumb
Xto let me win or offer me a contract, so here goes their opportunity to
Xmake some money. Not mine, however, since I am going to try the sh*r*ware
Xconcept. So, if you like the program, feel free to send me some $$, or even
X$$$ if you feel like it.
X
X    What _is_ MSH ? Well, if you ever heard of CrossDos, it is about the
Xsame thing. Only better, since I wrote it :-) If you never heard of
XCrossDos: MSH is a (set of) programs that enable you to use IBM-PC
Xdiskettes in your Amiga, just as if they were regular Amiga disks.
XSomething you probably thought or were told to be impossible!
X
X    There exist other programs that will copy files to and/or from messy
Xdisks, but they do just that: copy. You are not able to use any other
Xprogram directly with files you have stored on a messy disk. But, with MSH,
Xthis is finally possible. It seems that several people at about the same
Xtime decided that it was time to write a program like MSH. Hence there is
Xalso CrossDos. The fundamental difference between MSH and CrossDos is that
Xyou immediately get a fully functional version of MSH, and you even get the
Xsource! (And I am a non-commercial hobbyist).
X
X    Of course, if you get the source, you won't get any warranty. The idea
Xis that if it works, you send me some $$ (preferably in some stronger
Xcurrency than the dollar, though); if it fails to work, you can fix it
Xyourself.
X
X    Well, enough talk. Some technical information can be found in the files
Xmsh.man and dev.man. Fanmail and money will always reach me at the
Xfollowing address:
X
XOlaf Seibert
XBeek 5
X5815 CS  Merselo
XThe Netherlands
X
X    Ordinary mail can also be addressed to the following address, which is
Xguaranteed to change before September 1991:
X
XOlaf Seibert
XVossendijk 149
X6534 TN  Nijmegen
XThe Netherlands
END_OF_FILE
if test 5192 -ne `wc -c <'doc/RELEASE-NOTES'`; then
    echo shar: \"'doc/RELEASE-NOTES'\" unpacked with wrong size!
fi
# end of 'doc/RELEASE-NOTES'
fi
if test -f 'doc/rx50notes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/rx50notes'\"
else
echo shar: Extracting \"'doc/rx50notes'\" \(3044 characters\)
sed "s/^X//" >'doc/rx50notes' <<'END_OF_FILE'
XArticle 7092 of comp.sys.amiga.tech:
XPath: estinc!mcdphx!asuvax!cs.utexas.edu!tut.cis.ohio-state.edu!giza.cis.ohio-state.edu!erd
XFrom: erd@giza.cis.ohio-state.edu (Ethan R Dicks)
XNewsgroups: comp.sys.amiga.tech
XSubject: How's this for an enhancement to MSH?
XKeywords: MSH messy-dos Manx digital VAX RX50
XMessage-ID: <77558@tut.cis.ohio-state.edu>
XDate: 24 Feb 90 22:11:53 GMT
XSender: news@tut.cis.ohio-state.edu
XReply-To: Ethan R Dicks <erd@cis.ohio-state.edu>
XDistribution: na
XOrganization: Ohio State University Computer and Information Science
XLines: 86
X
X
XI have an "enhancement" to MSH, the messydisk.device in particular.  I
Xhave been trying to read DEC RX-50 5-1/4" floppies for a long time now.
XThe drive I am using is a standard PC clone 5-1/4" drive attached to the
Xsmall circuit board found in the A1010 3-1/2" drive.  It works fine with
XAmigaDOS, CrossDOS and MSH.  I want to read RX-50 floppies.  The chart
XI have from the DEC manual looks like this...
X
X"GAP 1"		GAP 1:		47  x  0x4E
X
X
X		SYNCH:		8   x  0x00
X		IDAM:		3   x  0xA1
X				1   x  0xFE
X		TRACK:		(physical track address)
X		SIDE:		(physical side number)
X		SECTR:		(physical sector number)
X[Repeat once	SIZE:		1   x  0x02  (512 bytes per sector)
X per sector ]	2 CRC:		2      CRC bytes
X		GAP 2:		22  x  0x4E
X		SYNCH:		12  x  0x00
X		DAM:		3   x  0xA1
X				1   x  0xFB
X 		DATA:		512 x  0xE5
X		2 CRC:		2      CRC bytes
X		GAP 3:		48  x  0x4E
X
X
X		GAP 4:		6250 minus sum of bytes up to GAP 4 x 0x4E
X
X
XThe same chart lists PC floppies as follows...
X
X
X"GAP 1"		GAP 1A:		80  x  0x4E
X		SYNCH:		12  x  0x00
X		INDEX:		3   x  0xC2
X				1   x  0xFC
X		GAP1B:		50  x  0x4E
X
X
X
X		SYNCH:		12  x  0x00
X		IDAM:		3   x  0xA1
X				1   x  0xFE
X		TRACK:		(physical track address)
X		SIDE:		(physical side number)
X		SECTR:		(physical sector number)
X[Repeat once	SIZE:		1   x  0x02  (512 bytes per sector)
X per sector ]	2 CRC:		2      CRC bytes
X		GAP 2:		22  x  0x4E
X		SYNCH:		12  x  0x00
X		DAM:		3   x  0xA1
X				1   x  0xFB
X 		DATA:		512 x  0xE5
X		2 CRC:		2      CRC bytes
X		GAP 3:		64  x  0x4E
X
X
X		GAP 4:		6250 minus sum of bytes up to GAP 4 x 0x4E
X
X
XAs you can see, the formats are extremely familiar.  I would perform the
Xchange myself, but I have Lattice, not Manx.  I would be very happy to see
Xa messydisk.device which supports that track format, and a diskette head
Xgeometry of 10 sectors/track by 1 head by 80 tracks (400kb).  For someone
Xwith Manx, the change is utterly trivial, but for me, almost impossible.
XOnce I can read the blocks on a diskette, I intend to write two new file
Xsystems for the Amiga: RT-11 format and ODS-1 or ODS-2 FILES-11 format, 
Xso that I can directly read diskettes written on PDP-11s or VAXen.  The 
Xother possibility is to write tar floppies, but I still need to be able to
Xread the sectors.
X
XThanks much.
X
X-ethan
X
X
X
X
X
X--
XEthan R. Dicks       | ######  This signifies that the poster is a member in
XSoftware Results Corp|   ##    good sitting of Inertia House: Bodies at rest.
X940 Freeway Drive N. |   ##
XColumbus OH    43229 | ######  "You get it, you're closer."
X
X
END_OF_FILE
if test 3044 -ne `wc -c <'doc/rx50notes'`; then
    echo shar: \"'doc/rx50notes'\" unpacked with wrong size!
fi
# end of 'doc/rx50notes'
fi
if test ! -d 'src' ; then
    echo shar: Creating directory \"'src'\"
    mkdir 'src'
fi
if test -f 'src/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/Makefile'\"
else
echo shar: Extracting \"'src/Makefile'\" \(1916 characters\)
sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
X# $Id: Makefile,v 1.30 90/06/04 23:20:34 Rhialto Rel $
X#
X# Makefile for messydos file system handler and -device, for use with the
X# Manx C compiler version 3.6.
X#
X# This code is (C) Copyright 1989,1990 by Olaf Seibert. All rights reserved.
X# May not be used or copied without a licence.
X
XHOBJ =	pack.o support.o hanmain.o hansec.o hanlock.o hanfile.o hanreq.o \
X	hancmd.o date.o
XHSRC =	pack.c support.c hanmain.c hansec.c hanlock.c hanfile.c hanreq.c \
X	hancmd.c date.c dos.h han.h
XDOBJ =	device.o devio.o
XDSRC =	device.c devio.c dev.h device.h
XXSRC =	messyfmt.c Makefile ignore.c die.c
X#DB =	 -DDEBUG -DHDEBUG
X#DB =	 -DHDEBUG
X#WACK =  -W
X
X#   Options: large code, large data, no startup code, use A4
X.c.o:
X	cc +Iamiga.syms +cdbrx3,5 $(DB) $*.c -o $@
X
Xall:	MessyFileSystem messydisk.device
Xutils:	die ignore messyfmt
Xdoc:	dev.man msh.man
X
Xmessydisk.device: $(DOBJ)
X	ln -o $@ $(WACK) $(DOBJ) -lcl
X
XMessyFileSystem:    $(HOBJ)
X	ln -o $@ $(WACK) $(HOBJ) -lcl
X
XDie:	die.c
X	cc +Iamiga.syms +x3,5 die.c
X	ln Die.o -lcl
X
XIgnore: ignore.c dev.h device.h
X	cc +Iamiga.syms +x3,5 ignore.c
X	ln Ignore.o -lcl
X
XMessyFmt:
X	cc +Iamiga.syms +x3,5 messyfmt.c
X	ln MessyFmt.o -lcl
X
Xdev.man: dev.n
X	nro dev.n >dev.man
X
Xmsh.man: msh.n
X	nro msh.n >msh.man
X
Xci:
X	RCS:ci -u $(HSRC) $(DSRC) $(XSRC)
X
Xco:
X	RCS:co -l $(HSRC) $(DSRC) $(XSRC)
X
X# DO NOT DELETE THIS LINE - important for making dependencies!
X#|.c|$*.o|
X#|.h|
X# From this line on, everything has been created by MakeDepend.
X# Anything you add yourself will be deleted automagically.
X
Xdate.o: dev.h han.h date.c
Xdevio.o: device.h dev.h devio.c
Xhanfile.o: dev.h han.h dos.h hanfile.c
Xsupport.o: dos.h support.c
Xdevice.o: device.h dev.h device.c
Xhanlock.o: dev.h han.h dos.h hanlock.c
Xhanmain.o: dev.h han.h dos.h hanmain.c
Xhansec.o: dev.h han.h dos.h hansec.c
Xhanreq.o: dos.h hanreq.c
Xmessyfmt.o: dev.h han.h messyfmt.c
Xpack.o: dev.h han.h dos.h pack.c
Xhancmd.o: dev.h han.h hancmd.c
END_OF_FILE
if test 1916 -ne `wc -c <'src/Makefile'`; then
    echo shar: \"'src/Makefile'\" unpacked with wrong size!
fi
chmod +x 'src/Makefile'
# end of 'src/Makefile'
fi
if test -f 'src/date.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/date.c'\"
else
echo shar: Extracting \"'src/date.c'\" \(3510 characters\)
sed "s/^X//" >'src/date.c' <<'END_OF_FILE'
X/*-
X * $Id: date.c,v 1.30 90/06/04 23:18:11 Rhialto Rel $
X * $Log:	date.c,v $
X * Revision 1.30  90/06/04  23:18:11  Rhialto
X * Release 1 Patch 3
X * 
X * DATE.C
X *
X * Two date conversion routines: DateStamp <-> MSDOS date/time.
X *
X * This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
X * not be used or copied without a licence.
X */
X
X#include <libraries/dos.h>
X#include "han.h"
X
X#define BASEYEAR	    1978
X#define DAYS_PER_YEAR	    365
X#define HOURS_PER_DAY	    24
X#define MINUTES_PER_HOUR    60
X#define SECONDS_PER_MINUTE  60
X
X#define DAYS_PER_WEEK	    7
X#define MONTHS_PER_YEAR     12
X
X#define MINUTES_PER_DAY     (MINUTES_PER_HOUR * HOURS_PER_DAY)
X#define SECONDS_PER_DAY     ((long) SECONDS_PER_MINUTE * \
X			     MINUTES_PER_HOUR * HOURS_PER_DAY)
X
X#define LeapYear(year)  ((year & 3) == 0)   /* From 1-Mar-1901 to 28-Feb-2100 */
X
Xint daycount[MONTHS_PER_YEAR] = {
X	31,	28,    31,    30,    31,    30,
X	31,	31,    30,    31,    30,    31
X};
X
Xvoid
XToDateStamp(datestamp, date, time)
Xstruct DateStamp *datestamp;
Xword date;
Xword time;
X{
X    {
X	int hours, minutes, seconds;
X
X	seconds = (time & 31) * 2;
X	time >>= 5;
X	minutes = time & 63;
X	time >>= 6;
X	hours = time;
X
X	datestamp->ds_Minute = MINUTES_PER_HOUR * hours + minutes;
X	datestamp->ds_Tick = TICKS_PER_SECOND * seconds;
X    }
X
X    {
X	ulong i, j, t;
X	int year, month, day;
X
X	if (date < DATE_MIN)
X	    date = DATE_MIN;
X
X	day = date & 31;
X	date >>= 5;
X	month = (date & 15) - 1;
X	date >>= 4;
X	year = date + 1980;
X
X	if ((unsigned)month > 11 ||
X	    (unsigned)day > (unsigned)daycount[month]) {
X	    day = 31;
X	    month = 11;
X	    year = 1979;
X	}
X
X	j = year - BASEYEAR;
X
X	/* Get the next lower full leap period (4 years and a day) since ... */
X	t = (year - BASEYEAR) & ~3;
X	i = t;
X	t = (t / 4) * (4 * DAYS_PER_YEAR + 1);
X
X	/* t now is the number of days in 4 whole years since ... */
X
X	/*dbprintf(("ly0: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/
X	while (i < j) {
X	    /*dbprintf(("ly1: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/
X	    t += DAYS_PER_YEAR;
X	    if (LeapYear(i + BASEYEAR)) {
X		/*dbprintf(("leap year\n"));*/
X		t++;
X	    }
X	    i++;
X	}
X
X	/* t now is the number of days in whole years since ... */
X
X	/*dbprintf(("m0:  i=%ld j=%ld t=%ld\n", i, j, t));*/
X	for (i = 0; i < month; i++) {
X	    /*dbprintf(("m1: i=%ld j=%ld t=%ld\n", i, j, t));*/
X	    t += daycount[i];
X	    if (i == 1 && LeapYear(year)) {
X		t++;
X	    }
X	}
X
X	/* t now is the number of days in whole months since ... */
X
X	t += day - 1;
X
X	/* t now is the number of days in whole days since ... */
X
X	datestamp->ds_Days = t;
X    }
X}
X
Xvoid
XToMSDate(date, time, datestamp)
Xword *date;
Xword *time;
Xregister struct DateStamp *datestamp;
X{
X    {
X	word hours, minutes, seconds;
X
X	hours = datestamp->ds_Minute / MINUTES_PER_HOUR;
X	minutes = datestamp->ds_Minute % MINUTES_PER_HOUR;
X	seconds = datestamp->ds_Tick / TICKS_PER_SECOND;
X
X	*time = (hours << 11) | (minutes << 5) | (seconds / 2);
X    }
X    {
X	register long days, i, t;
X	int year, month, day;
X
X	days = datestamp->ds_Days;
X
X	year = BASEYEAR + (days/(4*DAYS_PER_YEAR+1)) * 4;
X	days %= 4 * DAYS_PER_YEAR + 1;
X	while (days) {
X		t = DAYS_PER_YEAR;
X		if (LeapYear(year))
X			t++;
X		if (days < t)
X			break;
X		days -= t;
X		year++;
X	}
X	days++;
X	for (i = 0; i < MONTHS_PER_YEAR; i++) {
X		t = daycount[i];
X		if (i == 1 && LeapYear(year))
X			t++;
X		if (days <= t)
X			break;
X		days -= t;
X	}
X	month = i + 1;
X	day = days;
X
X	*date = ((year - 1980) << 9) | (month << 5) | day;
X    }
X}
END_OF_FILE
if test 3510 -ne `wc -c <'src/date.c'`; then
    echo shar: \"'src/date.c'\" unpacked with wrong size!
fi
# end of 'src/date.c'
fi
if test -f 'src/dev.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/dev.h'\"
else
echo shar: Extracting \"'src/dev.h'\" \(1676 characters\)
sed "s/^X//" >'src/dev.h' <<'END_OF_FILE'
X/*-
X *  $Id: dev.h,v 1.30 90/06/04 23:19:21 Rhialto Rel $
X *  $Log:	dev.h,v $
X * Revision 1.30  90/06/04  23:19:21  Rhialto
X * Release 1 Patch 3
X * 
X *  Include file for users of the messydisk.device
X-*/
X
X#ifndef EXEC_TYPES_H
X#include "exec/types.h"
X#endif
X#ifndef EXEC_MEMORY_H
X#include "exec/memory.h"
X#endif
X#ifndef EXEC_SEMAPHORES_H
X#include "exec/semaphores.h"
X#endif
X#ifndef EXEC_INTERRUPTS_H
X#include "exec/interrupts.h"
X#endif
X#ifndef EXEC_NODES_H
X#include "exec/nodes.h"
X#endif
X#ifndef EXEC_PORTS_H
X#include "exec/ports.h"
X#endif
X#ifndef EXEC_IO_H
X#include "exec/io.h"
X#endif
X#ifndef EXEC_ERRORS_H
X#include "exec/errors.h"
X#endif
X#ifndef EXEC_DEVICES_H
X#include "exec/devices.h"
X#endif
X#ifndef RESOURCES_DISK_H
X#include "resources/disk.h"
X#endif
X#ifndef RESOURCES_CIA_H
X#include "resources/cia.h"
X#endif
X#ifndef HARDWARE_CUSTOM_H
X#include "hardware/custom.h"
X#endif
X#ifndef HARDWARE_CIA_H
X#include "hardware/cia.h"
X#endif
X#ifndef HARDWARE_ADKBITS_H
X#include "hardware/adkbits.h"
X#endif
X#ifndef HARDWARE_DMABITS_H
X#include "hardware/dmabits.h"
X#endif
X#ifndef HARDWARE_INTBITS_H
X#include "hardware/intbits.h"
X#endif
X#ifndef DEVICES_TRACKDISK_H
X#include "devices/trackdisk.h"
X#endif
X
Xtypedef unsigned char byte;
Xtypedef unsigned short word;
Xtypedef unsigned long ulong;
X
X#define IOMDB_40TRACKS	7
X#define IOMDF_40TRACKS	(1<<7)
X
X#define DiskResource	    DiscResource	/* Aargh! */
X#define DiskResourceUnit    DiscResourceUnit	/* Aargh! */
X
X/*
X * Some default values
X */
X
X#define MS_BPS	    512 	/* Bytes per sector */
X#define MS_SPT	    9		/* Default sectors per track */
X#define MS_SPT_MAX  10		/* Max sectors per track */
X#define MS_NSIDES   2		/* Tracks per cylinder */
END_OF_FILE
if test 1676 -ne `wc -c <'src/dev.h'`; then
    echo shar: \"'src/dev.h'\" unpacked with wrong size!
fi
# end of 'src/dev.h'
fi
if test -f 'src/device.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/device.h'\"
else
echo shar: Extracting \"'src/device.h'\" \(5364 characters\)
sed "s/^X//" >'src/device.h' <<'END_OF_FILE'
X/*-
X *  $Id: device.h,v 1.30 90/06/04 23:19:28 Rhialto Rel $
X *  $Log:	device.h,v $
X * Revision 1.30  90/06/04  23:19:28  Rhialto
X * Release 1 Patch 3
X * 
X *  This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
X *  not be used or copied without a licence.
X-*/
X
X#define MD_NUMUNITS	4
X
X#define VERSION 	34L
X#define REVISION	8
X
X#asm
XVERSION     equ 	34
XRTPRI	    equ 	0
X#endasm
X
Xstruct MessyDevice {
X    struct Device   md_Dev;
X    struct MessyUnit *md_Unit[MD_NUMUNITS];
X    long	    md_Seglist;
X    struct SignalSemaphore md_HardwareUse;
X    byte	   *md_Rawbuffer;
X    byte	    md_MfmDecode[128];
X};
X
X#define dev_Node	md_Dev.dd_Library.lib_Node
X#define dev_Flags	md_Dev.dd_Library.lib_Flags
X#define dev_NegSize	md_Dev.dd_Library.lib_NegSize
X#define dev_PosSize	md_Dev.dd_Library.lib_PosSize
X#define dev_Version	md_Dev.dd_Library.lib_Version
X#define dev_Revision	md_Dev.dd_Library.lib_Revision
X#define dev_IdString	md_Dev.dd_Library.lib_IdString
X#define dev_OpenCnt	md_Dev.dd_Library.lib_OpenCnt
X
Xstruct MessyUnit {
X    struct MsgPort  mu_Port;
X    short	    mu_OpenCnt;
X    short	    mu_UnitNr;
X    byte	    mu_Flags;
X    char	    mu_InitSectorStatus;
X    ulong	    mu_ChangeNum;
X    char	    mu_DiskState;
X    byte	    mu_DmaSignal;
X    short	    mu_SectorsPerTrack; /* The nominal #sectors/track */
X    short	    mu_CurrentSectors;	/* The current #sectors on this track */
X    short	    mu_CurrentTrack;	/* Position of the head, and */
X    short	    mu_CurrentSide;	/* what's in the track buffer */
X    short	    mu_TrackChanged;
X    struct DiskResourceUnit mu_DRUnit;
X    struct MsgPort  mu_DiskReplyPort;
X    struct IOExtTD *mu_DiskIOReq;
X    struct IOStdReq *mu_DiskChangeReq;
X    struct Interrupt mu_DiskChangeInt;
X    struct MinList  mu_ChangeIntList;
X    short	    mu_NumCyls;
X    byte	    mu_TrackBuffer[MS_SPT_MAX * MS_BPS];   /* Must be word aligned */
X    word	    mu_CrcBuffer[MS_SPT_MAX];
X    char	    mu_SectorStatus[MS_SPT_MAX];
X};
X
X#define     TDERR_NoError   0
X#define     CRC_UNCHECKED   -1
X#define     CRC_CHANGED     -2
X
X#define UNITB_ACTIVE	0
X#define UNITF_STOPPED	(1<<2)
X#define UNITF_WAKETASK	(1<<3)
X
X#define STATEF_UNKNOWN	(1<<0)
X#define STATEF_PRESENT	(1<<1)
X#define STATEF_WRITABLE (1<<2)
X
X/* Some constants related to #defines */
X#asm
XMS_BPS		    equ 512
XMS_BPScode	    equ 2		    ; 2log(MSBPS/128)
XLOG2_MS_BPS	    equ 9
XMS_SPT		    equ 9
XMS_SPT_MAX	    equ 10
X#endasm
X
Xtypedef struct MessyDevice DEV;
Xtypedef struct MessyUnit   UNIT;
X
X
X#define TASKPRI     5L
X#define TASKSTACK   1024L
X
X/*
X *  Which of the device commands are real, and which are
X *  routed to trackdisk.device.
X */
X
X/*  #define CMD_Invalid     /**/
X/*  #define CMD_Reset	    /**/
X/*  #define CMD_Read	    /**/
X/*  #define CMD_Write	    /**/
X/*  #define CMD_Update	    /**/
X/*  #define CMD_Clear	    /**/
X/*  #define CMD_Stop	    /**/
X/*  #define CMD_Start	    /**/
X/*  #define CMD_Flush	    /**/
X    #define TD_Motor	    TrackdiskGateway
X/*  #define TD_Seek	    /**/
X/*  #define TD_Format	    /**/
X    #define TD_Remove	    TrackdiskGateway
X/*  #define TD_Changenum    /**/
X    #define TD_Changestate  TrackdiskGateway
X    #define TD_Protstatus   TrackdiskGateway
X    #define TD_Rawread	    TrackdiskGateway
X    #define TD_Rawwrite     TrackdiskGateway
X    #define TD_Getdrivetype TrackdiskGateway
X    #define TD_Getnumtracks TrackdiskGateway
X/*  #define TD_Addchangeint /**/
X/*  #define TD_Remchangeint /**/
X
X#define STRIP(cmd)  ((unsigned char)cmd)
X#define IMMEDIATE   ((1<<CMD_INVALID)|(1<<CMD_RESET)|\
X		     (1<<CMD_STOP)|(1<<CMD_START)|(1<<CMD_FLUSH)|\
X		     (1L<<TD_ADDCHANGEINT))
X#define PerformIO(ioreq, unit) \
X		    (funcTable[STRIP(ioreq->io_Command)])(ioreq, unit)
X
Xextern DEV *MakeLibrary();
Xextern struct Task *FindTask();
Xextern struct Task *CreateTask();
X
X/*
X *  Forward declarations:
X */
X
Xextern char EndCode;
Xextern void Init(), _DevOpen(), _DevClose(), _DevExpunge(), _LibNull();
Xextern void _DevBeginIO(), _DevAbortIO();
X
Xextern char DevName[], idString[];
X
Xextern DEV *CInit();
Xextern void DevOpen();
Xextern long DevClose(), DevExpunge();
Xextern void DevBeginIO(), TermIO();
Xextern long DevAbortIO();
X
Xextern void WakePort();
Xextern void UnitTask();
X
Xextern int DevInit();
Xextern UNIT *UnitInit();
Xextern void DiskChangeHandler();
X
Xextern void TrackdiskGateway();
Xextern void CMD_Invalid();
Xextern void CMD_Reset();
Xextern void CMD_Read();
Xextern void CMD_Write();
Xextern void CMD_Update();
Xextern void CMD_Clear();
Xextern void CMD_Stop();
Xextern void CMD_Start();
Xextern void CMD_Flush();
Xextern void TD_Seek();
Xextern void TD_Format();
Xextern void TD_Changenum();
Xextern void TD_Addchangeint();
Xextern void TD_Remchangeint();
X
Xextern struct DiskResource *OpenResource();
Xextern struct MsgPort *DeviceProc();
Xextern struct MsgPort *CreatePort();
Xextern struct IOExtTD *CreateExtIO();
Xextern void    *GetUnit(), *GetMsg();
Xextern long	Wait();
Xextern void    *AllocMem(), FreeMem();
Xextern byte    *index(), *rindex();
X
Xextern int	ReadTrack();
Xextern void	InitDecoding();
Xextern int	TDSeek();
Xextern int	TDMotorOn();
Xextern int	TDMotorOff();
Xextern int	TDGetNumCyls();
Xextern void    *GetDrive();
Xextern void	FreeDrive();
Xextern int	DevOpenUp();
Xextern int	DevCloseDown();
Xextern int	GetTrack();
Xextern int	CheckRequest();
X
X#ifndef READONLY
Xextern int	InitWrite();
Xextern void	FreeBuffer();
Xextern void	EncodeTrack();
X#endif
END_OF_FILE
if test 5364 -ne `wc -c <'src/device.h'`; then
    echo shar: \"'src/device.h'\" unpacked with wrong size!
fi
# end of 'src/device.h'
fi
if test -f 'src/die.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/die.c'\"
else
echo shar: Extracting \"'src/die.c'\" \(397 characters\)
sed "s/^X//" >'src/die.c' <<'END_OF_FILE'
X/*-
X *  DIE.C
X *
X *  This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
X *  not be used or copied without a licence.
X-*/
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X    struct MsgPort *filehandler, *DeviceProc();
X
X    if (argc == 2) {
X	if (filehandler = DeviceProc(argv[1])) {
X	    dos_packet(filehandler, ACTION_DIE, DOSTRUE);
X	}
X    } else
X	printf("Usage: die DEV:\n");
X}
X
END_OF_FILE
if test 397 -ne `wc -c <'src/die.c'`; then
    echo shar: \"'src/die.c'\" unpacked with wrong size!
fi
# end of 'src/die.c'
fi
if test -f 'src/dos.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/dos.h'\"
else
echo shar: Extracting \"'src/dos.h'\" \(3014 characters\)
sed "s/^X//" >'src/dos.h' <<'END_OF_FILE'
X
X/*
X *  $Id: dos.h,v 1.30 90/06/04 23:18:20 Rhialto Rel $
X *  $Log:	dos.h,v $
X * Revision 1.30  90/06/04  23:18:20  Rhialto
X * Release 1 Patch 3
X * 
X */
X
X#ifndef EXEC_TYPES_H
X#include "exec/types.h"
X#endif
X#ifndef EXEC_MEMORY_H
X#include "exec/memory.h"
X#endif
X#ifndef EXEC_INTERRUPTS_H
X#include "exec/interrupts.h"
X#endif
X#ifndef EXEC_NODES_H
X#include "exec/nodes.h"
X#endif
X#ifndef EXEC_PORTS_H
X#include "exec/ports.h"
X#endif
X#ifndef EXEC_IO_H
X#include "exec/io.h"
X#endif
X#ifndef LIBRARIES_DOS_H
X#include "libraries/dos.h"
X#endif
X#ifndef LIBRARIES_DOSEXTENS_H
X#include "libraries/dosextens.h"
X#endif
X#ifndef LIBRARIES_FILEHANDLER_H
X#include "libraries/filehandler.h"
X#endif
X#ifndef DEVICES_TRACKDISK_H
X#include "devices/trackdisk.h"
X#endif
X#ifndef DEVICES_TIMER_H
X#include "devices/timer.h"
X#endif
X
X/*
X *  ACTIONS which do not exist in dosextens.h but which indeed exist on
X *  the Amiga.
X */
X
X#define ACTION_MORECACHE    18L
X#define ACTION_FLUSH	    27L
X#define ACTION_RAWMODE	    994L
X#define ACTION_OPENRW	    1004L
X#define ACTION_OPENOLD	    1005L
X#define ACTION_OPENNEW	    1006L
X#define ACTION_CLOSE	    1007L
X#define ACTION_SEEK	    1008L
X
X#ifndef FIBB_HIDDEN
X#define FIBB_HIDDEN 7L
X#define FIBF_HIDDEN (1L<<FIBB_HIDDEN)
X#endif
X
X#ifndef DE_DOSTYPE
X#define DE_DOSTYPE	    16L
X#endif
X
X#define CTOB(x) (void *)(((long)(x))>>2)    /*  BCPL conversion */
X#define BTOC(x) (void *)(((long)(x))<<2)
X
X#define bmov(ss,dd,nn) CopyMem(ss,dd,(ulong)(nn))   /* Matt's habit */
X
X#define DOS_FALSE   0L
X#define DOS_TRUE    -1L
X
Xtypedef struct Interrupt	INTERRUPT;
Xtypedef struct Task		TASK;
Xtypedef struct FileLock 	LOCK;
Xtypedef struct FileInfoBlock	FIB;
Xtypedef struct DosPacket	PACKET;
Xtypedef struct Process		PROC;
Xtypedef struct DeviceNode	DEVNODE;
Xtypedef struct DeviceList	DEVLIST;
Xtypedef struct DosInfo		DOSINFO;
Xtypedef struct RootNode 	ROOTNODE;
Xtypedef struct FileHandle	FH;
Xtypedef struct MsgPort		PORT;
Xtypedef struct Message		MSG;
Xtypedef struct MinList		LIST;
Xtypedef struct MinNode		NODE;
Xtypedef struct DateStamp	STAMP;
Xtypedef struct InfoData 	INFODATA;
Xtypedef struct DosLibrary	DOSLIB;
X
X#define PType (packet->dp_Type)
X#define PArg1 (packet->dp_Arg1)
X#define PArg2 (packet->dp_Arg2)
X#define PArg3 (packet->dp_Arg3)
X#define PArg4 (packet->dp_Arg4)
X#define PRes1 (packet->dp_Res1)
X#define PRes2 (packet->dp_Res2)
X
X#define dl_MSFileLockList   dl_unused
X
X
X/*
X *  (void *)  in C means 'pointer to anything'.  I use it
X *  extensively.
X */
X
Xextern void *AbsExecBase;
X
Xextern struct MsgPort *CreatePort();
Xextern void *AllocMem(), *RemHead(), *GetMsg();
Xextern void *FindTask(), *Open(), *OpenLibrary();
X
Xextern void   *dosalloc(), *NextNode(), *GetHead(), *GetTail();
Xextern void   btos(), returnpacket();
X
Xextern char *typetostr();
X
Xextern struct DeviceList *NewVolNode();
Xextern void FreeVolNode();
Xextern struct FileLock *NewFileLock();
Xextern long FreeFileLock();
Xextern int DiskRemoved();
Xextern void DiskInserted();
Xextern DEVLIST *WhichDiskInserted();
Xextern int CheckRead();
Xextern int CheckWrite();
END_OF_FILE
if test 3014 -ne `wc -c <'src/dos.h'`; then
    echo shar: \"'src/dos.h'\" unpacked with wrong size!
fi
# end of 'src/dos.h'
fi
if test -f 'src/han.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/han.h'\"
else
echo shar: Extracting \"'src/han.h'\" \(9315 characters\)
sed "s/^X//" >'src/han.h' <<'END_OF_FILE'
X/*-
X *  $Id: han.h,v 1.30 90/06/04 23:18:28 Rhialto Rel $
X *  $Log:	han.h,v $
X * Revision 1.30  90/06/04  23:18:28  Rhialto
X * Release 1 Patch 3
X * 
X *  The header file for the MESSYDOS: file system handler
X *
X *  This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
X *  not be used or copied without a licence.
X-*/
X
X#include "dev.h"
X
X#define MODE_READWRITE	1004L
X#define MODE_CREATEFILE (1L<<31)
X#define FILE_DIR     2
X#define FILE_FILE   -3
X
X/* #define MS_BPS      512	/* Bytes per sector */
X#define MS_SPC	    2		/* Sectors per cluster */
X#define MS_RES	    1		/* Reserved sectors (boot block) */
X#define MS_NFATS    2		/* Number of FATs */
X#define MS_NDIRS    112 	/* Number of directory entries */
X#define MS_NSECTS   1440	/* total number of sectors */
X#define MS_SPF	    3		/* Sectors per FAT */
X/* #define MS_SPT      9	/* Sectors per track */
X/* #define MS_SPT_MAX  9	/* Max sectors per track */
X/* #define MS_NSIDES   2	/* Tracks per cylinder */
X#define MS_ROOTDIR  (MS_RES + MS_SPF * MS_NFATS)
X#define MS_DIRENTSIZE  sizeof(struct MsDirEntry) /* size of a directory entry */
X
X#define MS_FIRSTCLUST	2	/* Very strange convention... */
X
X#define FAT_EOF     0xFFFF	/* end of file FAT entry */
X#define FAT_UNUSED  0		/* unused block */
X#define SEC_EOF     -1		/* end of FAT chain */
X#define ROOT_SEC    -1		/* where the root directory 'is' */
X
X#define DIR_DELETED	    0xE5
X#define DIR_DELETED_MASK    0x80
X
X/*
X * This structure has its byte order wrong, when it is on the disk.
X */
X
Xstruct MsDirEntry {
X    byte	    msd_Name[8];
X    byte	    msd_Ext[3];
X    byte	    msd_Attributes;
X    byte	    msd_Pad1[10];
X    word	    msd_Time;
X    word	    msd_Date;
X    word	    msd_Cluster;
X    ulong	    msd_Filesize;
X};
X
X#define ATTR_READONLY	    0x01
X#define ATTR_HIDDEN	    0x02
X#define ATTR_SYSTEM	    0x04
X#define ATTR_VOLUMELABEL    0x08
X#define ATTR_DIRECTORY	    0x10
X#define ATTR_ARCHIVED	    0x20
X
X#define ATTR_DIR	    (ATTR_DIRECTORY | ATTR_VOLUMELABEL)
X
X#define DATE_MIN	    0x21
X
Xstruct DirEntry {
X    struct MsDirEntry de_Msd;
X    word	    de_Sector;
X    word	    de_Offset;
X};
X
Xstruct DiskParam {
X    word	    bps;	/* bytes per sector. max MS_BPS supported */
X    byte	    spc;	/* sectors per cluster */
X    word	    res;	/* reserved sectors (boot block) */
X    byte	    nfats;	/* number of fats */
X    word	    ndirs;	/* number of directory entries */
X    word	    nsects;	/* total number of sectors on disk */
X    byte	    media;	/* media byte */
X    word	    spf;	/* sectors per fat */
X    word	    spt;	/* sectors per track. Only MS_SPT
X				 * supported */
X    word	    nsides;	/* # sides. Max MS_NSIDES supported */
X    word	    nhid;	/* Number of hidden sectors */
X    /* derived parameters */
X    word	    start;	/* sector of cluster 0 */
X    word	    maxclst;	/* highest cluster number */
X    word	    rootdir;	/* first sector of root dir */
X    word	    ndirsects;	/* # of root directory sectors */
X    word	    datablock;	/* first block available for files &c */
X    word	    bpc;	/* bytes per cluster */
X    word	    nsectsfree; /* amount of free space */
X    long	    lowcyl;	/* offset to lowcyl */
X    struct DirEntry vollabel;	/* copy of volume label */
X    word	    fat16bits;	/* Is the FAT 16 bits/entry? */
X};
X
X/*
X * A pointer to an MSFileLock is put into the fl_Key field of a DOS
X * FileLock structure. We share the MSFileLock with all FileLocks on the
X * same file. This way, you can compare FileLocks based on their fl_Key
X * and fl_Task fields, as seems to be done sometimes. Also, a pointer to
X * an MSFileLock is put in MSFileHandles.
X *
X * For ease, we keep a copy of the directory entry in core, WITH THE BYTE
X * ORDER CORRECTED FOR THIS PROCESSOR.
X */
X
Xstruct MSFileLock {
X    struct MinNode  msfl_Node;
X    short	    msfl_Refcount;	/* -1: exclusive, >0: # of shared
X					 * locks */
X    struct MSFileLock *msfl_Parent;	/* Pointer to parent directory */
X    struct MsDirEntry msfl_Msd; /* Copy of directory entry */
X    word	    msfl_DirSector;	/* Location of directory entry */
X    word	    msfl_DirOffset;
X};
X
X/*
X * A pointer to an MSFileHandle is put into the fh_Arg1 field of a DOS
X * FileHandle. We get that value with many DOS packets that manipulate the
X * contents of a file.
X */
X
Xstruct MSFileHandle {
X    struct MSFileLock *msfh_FileLock;
X    long	    msfh_SeekPos;
X    word	    msfh_Cluster;
X};
X
X/*
X * Return values of CompareNames.
X */
X
X#define CMP_NOT_EQUAL	    0	/* Names do not match at all */
X#define CMP_OK_DIR	    1	/* Name matches with a subdir entry */
X#define CMP_OK_FILE	    2	/* Name matches with a file entry */
X#define CMP_INVALID	    3	/* First part of name matches with a file
X				 * entry, or other invalid component name */
X#define CMP_FREE_SLOT	    5
X#define CMP_END_OF_DIR	    6
X
Xstruct LockList {
X    struct MinList  ll_List;
X    void	   *ll_Cookie;	/* we don't want to know what this is! */
X};
X
Xstruct CacheSec {
X    struct MinNode  sec_Node;
X    word	    sec_Number;
X    word	    sec_Refcount;
X    byte	    sec_Data[2];/* Really Disk.bps */
X};
X
X#define SEC_DIRTY   0x8000	/* Bit in sec_Refcount */
X
X#define OFFSETOF(tag, member)   ((long)(&((struct tag *)0)->member))
X
X#define     DELAY_OFF	    0	/* Motor is off */
X#define     DELAY_RUNNING1  1	/* Motor may be on */
X#define     DELAY_RUNNING2  2	/* Motor may be on */
X#define     DELAY_RUNNING   3	/* Running1 | 2 */
X#define     DELAY_DIRTY     4	/* We have dirty buffers to flush */
X
X
Xextern long	Wait();
Xextern struct MsgPort *CreatePort();
Xextern struct IOExtTD *CreateExtIO();
Xextern void    *AllocMem(), FreeMem();
Xextern byte    *index(), *rindex();
Xextern void    *CheckIO();
Xextern long	AutoRequest();
X
X/*
X * PACK.C
X */
Xextern char    *DevName;
Xextern long	UnitNr;
Xextern long	DosType;
Xextern ulong	DevFlags;
Xextern struct DosPacket *DosPacket;
Xextern struct DeviceList *VolNode;
Xextern short	DiskChanged;
X
X/*
X * HANMAIN.C
X */
Xextern byte	ToUpper();
Xextern long	lmin();
Xextern byte    *ZapSpaces();
Xextern byte    *ToMSName();
Xextern long	MSDiskInfo();
Xextern void	MSDiskInserted();
Xextern int	MSDiskRemoved();
Xextern void	HanCloseDown();
Xextern int	HanOpenUp();
X
X/*
X * HANSEC.C
X */
Xextern struct MsgPort *DiskReplyPort;
Xextern struct IOExtTD *DiskIOReq;
Xextern struct IOStdReq *DiskChangeReq;
Xextern struct DiskParam Disk;
Xextern byte    *Fat;
Xextern short	FatDirty;	/* Fat must be written to disk */
Xextern short	error;		/* To put the error value; for Result2 */
Xextern long	IDDiskState;	/* InfoData.id_DiskState */
Xextern long	IDDiskType;	/* InfoData.id_DiskType */
Xextern struct timerequest *TimeIOReq;	/* For motor-off delay */
Xextern struct MinList CacheList;/* Sector cache */
Xextern int	CurrentCache;	/* How many cached buffers do we have */
Xextern int	MaxCache;	/* Maximum amount of cached buffers */
Xextern ulong	BufMemType;
Xextern long	CacheBlockSize; /* Size of disk block + overhead */
Xextern int	DelayState;
Xextern byte    *Word8086;
Xextern word	Get8086Word();
Xextern word	OtherEndianWord();
Xextern ulong	OtherEndianLong();
Xextern void	OtherEndianMsd();
Xextern word	ClusterToSector();
Xextern word	ClusterOffsetToSector();
Xextern word	DirClusterToSector();
Xextern word	SectorToCluster();
Xextern word	NextCluster();
Xextern word	NextClusteredSector();
Xextern word	FindFreeSector();
Xextern struct CacheSec *FindSecByNumber();
Xextern struct CacheSec *FindSecByBuffer();
Xextern struct CacheSec *NewCacheSector();
Xextern void	FreeCacheSector();
Xextern void	InitCacheList();
Xextern void	FreeCacheList();
Xextern void	MSUpdate();
Xextern void	StartTimer();
Xextern byte    *GetSec();
Xextern byte    *EmptySec();
Xextern void	PutSec();
Xextern void	FreeSec();
Xextern void	MarkSecDirty();
Xextern void	WriteFat();
Xextern int	ReadBootBlock();
Xextern int	IdentifyDisk();
Xextern int	TDMotorOff();
Xextern int	TDGetNumCyls();
X
X/*
X * HANLOCK.C
X */
Xextern struct LockList *LockList;	/* List of all locked files we
X					 * have. Note this is not the same
X					 * as all locks we have */
Xextern struct MSFileLock *RootLock;	/* Lock on root directory */
Xextern struct MSFileLock *EmptyFileLock;	/* 2nd result of MSLock() */
X
Xextern struct DirEntry FakeRootDirEntry;
Xextern int	CompareNames();
Xextern void	NextDirEntry();
Xextern struct DirEntry *FindNext();
Xextern struct MSFileLock *MakeLock();
Xextern void	WriteLock();
Xextern void	PrintDirEntry();
Xextern struct MSFileLock *MSLock();
Xextern struct MSFileLock *MSDupLock();
Xextern struct MSFileLock *MSParentDir();
Xextern int	MSUnLock();
Xextern void	ExamineDirEntry();
Xextern int	MSExamine();
Xextern int	MSExNext();
Xextern long	MSSetProtect();
Xextern void	WriteFileLock();
Xextern void	UpdateFileLock();
Xextern struct LockList *NewLockList();
Xextern void	FreeLockList();
X
X/*
X * HANFILE.C
X */
Xextern int	GetFat();
Xextern void	FreeFat();
Xextern word	GetFatEntry();
Xextern void	SetFatEntry();
Xextern word	FindFreeCluster();
Xextern word	ExtendClusterChain();
Xextern void	FreeClusterChain();
Xextern struct MSFileHandle *MSOpen();
Xextern void	MSClose();
Xextern long	MSSeek();
Xextern long	MSRead();
Xextern long	MSWrite();
Xextern long	MSDeleteFile();
Xextern long	MSSetDate();
Xextern struct MSFileLock *MSCreateDir();
X
X/*
X * HANREQ.C
X */
Xextern short	Cancel; 	/* Cancel all R/W errors */
Xextern long	RetryRwError();
X
X/*
X * HANCMD.C
X */
Xextern void	HandleCommand();
X
X/*
X * DATE.C
X */
Xextern void	ToDateStamp();
Xextern void	ToMSDate();
END_OF_FILE
if test 9315 -ne `wc -c <'src/han.h'`; then
    echo shar: \"'src/han.h'\" unpacked with wrong size!
fi
# end of 'src/han.h'
fi
if test -f 'src/hancmd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/hancmd.c'\"
else
echo shar: Extracting \"'src/hancmd.c'\" \(995 characters\)
sed "s/^X//" >'src/hancmd.c' <<'END_OF_FILE'
X/*-
X * $Id: hancmd.c,v 1.30 90/06/04 23:18:03 Rhialto Rel $
X * $Log:	hancmd.c,v $
X * Revision 1.30  90/06/04  23:18:03  Rhialto
X * Release 1 Patch 3
X * 
X * HANCMD.C
X *
X * The code for the messydos file system handler
X *
X * Special commands through MSH::something file names.
X *
X * This code is (C) Copyright 1990 by Olaf Seibert. All rights reserved. May
X * not be used or copied without a licence.
X-*/
X
X#include "han.h"
X
X#ifdef HDEBUG
X#   define	debug(x)  dbprintf x
X#else
X#   define	debug(x)
X#endif
X
Xextern int	CheckBootBlock;
X
Xvoid
XHandleCommand(cmd)
Xregister char  *cmd;
X{
X#ifdef HDEBUG
X    if (cmd[1] == 'D') {
X	extern short	DBEnable;
X
X	DBEnable = name[2] & 0x0F;
X    } else
X#endif
X    if (cmd[1] == 'B') {
X	CheckBootBlock = atoi(&cmd[2]);
X    } else if (cmd[1] == 'F') {
X	if (cmd[2] == '+')
X	    DiskIOReq->iotd_Req.io_Flags |= IOMDF_40TRACKS;
X	else if (cmd[2] == '-')
X	    DiskIOReq->iotd_Req.io_Flags &= ~IOMDF_40TRACKS;
X	else
X	    DiskIOReq->iotd_Req.io_Flags = atoi(&cmd[2]);
X    }
X}
X
END_OF_FILE
if test 995 -ne `wc -c <'src/hancmd.c'`; then
    echo shar: \"'src/hancmd.c'\" unpacked with wrong size!
fi
# end of 'src/hancmd.c'
fi
if test -f 'src/hanreq.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/hanreq.c'\"
else
echo shar: Extracting \"'src/hanreq.c'\" \(2903 characters\)
sed "s/^X//" >'src/hanreq.c' <<'END_OF_FILE'
X/*-
X * $Id: hanreq.c,v 1.30 90/06/04 23:17:48 Rhialto Rel $
X * $Log:	hanreq.c,v $
X * Revision 1.30  90/06/04  23:17:48  Rhialto
X * Release 1 Patch 3
X * 
X *  HANREQ.C
X *
X *  The code for the messydos file system handler.
X *
X *  Read/Write error requesters.
X *
X *  This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
X *  not be used or copied without a licence.
X-*/
X
X#include "dos.h"
X#include "han.h"
X#include <intuition/intuition.h>
X
X#ifdef HDEBUG
X#   define	debug(x)  dbprintf x
X#else
X#   define	debug(x)
X#endif
X
Xshort		Cancel = 0;	/* Cancel all R/W errors */
X
Xstatic struct IntuiText Positive = {
X    AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X    AUTOLEFTEDGE, AUTOTOPEDGE, AUTOITEXTFONT,
X    (UBYTE *)"Retry",
X    AUTONEXTTEXT
X};
X
Xstatic struct IntuiText Negative = {
X    AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X    AUTOLEFTEDGE, AUTOTOPEDGE, AUTOITEXTFONT,
X    (UBYTE *)"Cancel",
X    AUTONEXTTEXT
X};
X
Xstatic struct IntuiText RwError[] = {
X    {
X	AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X	16,	      5,	   AUTOITEXTFONT,
X	(UBYTE *)"Messydos volume",
X	&RwError[1]
X    },
X    {
X	AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X	16,	      15,	   AUTOITEXTFONT,
X	(UBYTE *)NULL,
X	&RwError[2]
X    },
X    {
X	AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X	16,	      25,	   AUTOITEXTFONT,
X	(UBYTE *)"has a Read or Write error",
X	NULL
X    },
X};
X
Xstruct IntuiText MustReplace[] = {
X    {
X	AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X	16,	      5,	   AUTOITEXTFONT,
X	(UBYTE *)"You MUST!! replace messy volume",
X	&MustReplace[1]
X    },
X    {
X	AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X	16,	      15,	   AUTOITEXTFONT,
X	(UBYTE *)NULL,
X	&MustReplace[2]
X    },
X    {
X	AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X	16,	      25,	   AUTOITEXTFONT,
X	(UBYTE *)"in that floppy drive !!",
X	NULL
X    },
X};
X
Xlong
XRetryRwError(req)
Xstruct IOExtTD *req;
X{
X    register struct Window *window;
X    struct IntuiText *text;
X    long	    result;
X
X    if (Cancel)
X	goto fail;
X
X    if (DosPacket != NULL) { /* A user-requested action */
X	struct MsgPort *port;
X	struct Process *proc;
X
X	port = DosPacket->dp_Port;
X	if ((port->mp_Flags & PF_ACTION) != PA_SIGNAL)
X	    goto fail;
X	proc = (struct Process *)port->mp_SigTask;
X	if (proc->pr_Task.tc_Node.ln_Type != NT_PROCESS)
X	    goto fail;
X	window = (struct Window *)proc->pr_WindowPtr;
X	if (window == (struct Window *)-1)
X	    goto fail;
X    } else
X	window = NULL;
X
X    if (req->iotd_Req.io_Error == TDERR_DiskChanged) {
X	text = MustReplace;
X	DiskChanged = 0;
X    } else
X	text = RwError;
X
X    if (VolNode)
X	text[1].IText = (UBYTE *)BTOC(VolNode->dl_Name)+1;
X    else
X	text[1].IText = (UBYTE *)"";
X
Xagain:
X    result = AutoRequest(window, text, &Positive, &Negative,
X			 0L, 0L, 320L, 72L);
X
X    if (req->iotd_Req.io_Error == TDERR_DiskChanged && result != FALSE) {
X	TDChangeNum();  /* Get new disk change number */
X	DiskChanged = 0;
X    }
X
X    return result;
X
Xfail:
X    return FALSE;
X}
END_OF_FILE
if test 2903 -ne `wc -c <'src/hanreq.c'`; then
    echo shar: \"'src/hanreq.c'\" unpacked with wrong size!
fi
# end of 'src/hanreq.c'
fi
if test -f 'src/ignore.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/ignore.c'\"
else
echo shar: Extracting \"'src/ignore.c'\" \(1519 characters\)
sed "s/^X//" >'src/ignore.c' <<'END_OF_FILE'
X/*
X *  IGNORE.C
X *
X *  Makes it possible to ignore CRC errors.
X *
X *  This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved.
X *  May not be used or copied without a licence.
X */
X
X#include "dev.h"
X#include "device.h"
X
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X    struct MsgPort *port, *CreatePort();
X    struct IOExtTD *tdreq, *CreateExtIO();
X    UNIT *unit;
X    long unitnr;
X    int yesno;
X
X    if (argc < 2) {
X	Puts("Usage: ignore <unitnr> <YES/NO>\n");
X	Puts("       If Yes, CRC errors will be ignored.\n");
X	exit(1);
X    }
X
X    unitnr = atoi(argv[1]);
X    /*
X     *	Don't be misled by the name CRC_UNCHECKED.
X     *	It means the opposite happens.
X     */
X    if (argc > 2)
X	yesno = ((argv[2][0] & 0x5F) == 'Y') ? TDERR_NoError : CRC_UNCHECKED;
X    else
X	yesno = -42;
X
X    if (port = CreatePort(NULL, 0L)) {
X	if (tdreq = CreateExtIO(port, (long)sizeof(*tdreq))) {
X	    OpenDevice("messydisk.device", unitnr, tdreq, 0L);
X	    if (tdreq->iotd_Req.io_Device) {
X		unit = (UNIT *)tdreq->iotd_Req.io_Unit;
X		if (yesno != -42)
X		    unit->mu_InitSectorStatus = yesno;
X		else if (unit->mu_InitSectorStatus == CRC_UNCHECKED)
X		    Puts("No\n");
X		else
X		    Puts("Yes\n");
X		CloseDevice(tdreq);
X	    } else
X		Puts("Cannot OpenDevice messydisk\n");
X	    DeleteExtIO(tdreq);
X	} else
X	    Puts("No memory for I/O request\n");
X	DeletePort(port);
X    } else
X	Puts("No memory for replyport\n");
X}
X
XPuts(string)
Xchar *string;
X{
X    long Output();
X
X    Write(Output(), string, (long)strlen(string));
X}
X
X_wb_parse(){}
END_OF_FILE
if test 1519 -ne `wc -c <'src/ignore.c'`; then
    echo shar: \"'src/ignore.c'\" unpacked with wrong size!
fi
# end of 'src/ignore.c'
fi
if test -f 'src/messyfmt.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/messyfmt.c'\"
else
echo shar: Extracting \"'src/messyfmt.c'\" \(9671 characters\)
sed "s/^X//" >'src/messyfmt.c' <<'END_OF_FILE'
X/*
X * $Id: messyfmt.c,v 1.30 90/06/04 23:20:13 Rhialto Rel $
X * $Log:	messyfmt.c,v $
X * Revision 1.30  90/06/04  23:20:13  Rhialto
X * Release 1 Patch 3
X * 
X * MESSYFMT.C
X *
X * Formats a disk. Low-level formatting can also be done by mounting a file
X * system and using the AmigaDOS format command.
X *
X * This code is (C) Copyright 1989,1990 by Olaf Seibert. All rights reserved.
X * May not be used or copied without a licence.
X */
X
X#include <stdio.h>
X#include "han.h"
Xextern int	Enable_Abort;
X
Xulong		BootBlock[] = {
X    0xEB349049, 0x424D2020, 0x332E3200, 0x02020100,	/* ...IBM  3.2..... */
X    0x027000A0, 0x05F90300, 0x09000200, 0x00000000,
X    0x00000000, 0x00000000, 0x00000000, 0x0000000F,
X    0x00000000, 0x0100FA33, 0xC08ED0BC, 0x007C1607,
X    0xBB780036, 0xC5371E56, 0x1653BF2B, 0x7CB90B00,
X    0xFCAC2680, 0x3D007403, 0x268A05AA, 0x8AC4E2F1,
X    0x061F8947, 0x02C7072B, 0x7CFBCD13, 0x7267A010,
X    0x7C98F726, 0x167C0306, 0x1C7C0306, 0x0E7CA33F,
X    0x7CA3377C, 0xB82000F7, 0x26117C8B, 0x1E0B7C03,
X    0xC348F7F3, 0x0106377C, 0xBB0005A1, 0x3F7CE896,
X    0x00B80102, 0xE8AA0072, 0x198BFBB9, 0x0B00BECD,
X    0x7DF3A675, 0x0D8D7F20, 0xBED87DB9, 0x0B00F3A6,
X    0x7418BE6E, 0x7DE86100, 0x32E4CD16, 0x5E1F8F04,
X    0x8F4402CD, 0x19BEB77D, 0xEBEBA11C, 0x0533D2F7,
X    0x360B7CFE, 0xC0A23C7C, 0xA1377CA3, 0x3D7CBB00,
X    0x07A1377C, 0xE84000A1, 0x187C2A06, 0x3B7C4050,
X    0xE84E0058, 0x72CF2806, 0x3C7C760C, 0x0106377C,
X    0xF7260B7C, 0x03D8EBD9, 0x8A2E157C, 0x8A16FD7D,
X    0x8B1E3D7C, 0xEA000070, 0x00AC0AC0, 0x7422B40E,
X    0xBB0700CD, 0x10EBF233, 0xD2F73618, 0x7CFEC288,
X    0x163B7C33, 0xD2F7361A, 0x7C88162A, 0x7CA3397C,
X    0xC3B4028B, 0x16397CB1, 0x06D2E60A, 0x363B7C8B,
X    0xCA86E98A, 0x16FD7D8A, 0x362A7CCD, 0x13C30D0A,
X    0x4E6F6E2D, 0x53797374, 0x656D2064, 0x69736B20,	/* Non-System disk  */
X    0x6F722064, 0x69736B20, 0x6572726F, 0x720D0A52,	/* or disk error..R */
X    0x65706C61, 0x63652061, 0x6E642073, 0x7472696B,	/* eplace and strik */
X    0x6520616E, 0x79206B65, 0x79207768, 0x656E2072,	/* e any key when r */
X    0x65616479, 0x0D0A000D, 0x0A446973, 0x6B20426F,	/* eady.....Disk Bo */
X    0x6F742066, 0x61696C75, 0x72650D0A, 0x0049424D,	/* ot failure...IBM */
X    0x42494F20, 0x20434F4D, 0x49424D44, 0x4F532020,	/* BIO	COMIBMDOS   */
X    0x434F4D00, 0x00000000, 0x00000000, 0x00000000,	/* COM............. */
X    0x00000000, 0x00000000, 0x00000000, 0x000055AA,
X};
X
Xbyte	       *DiskTrack;
Xlong		TrackSize;
Xint		Track;
Xint		LowTrack;
Xword		nsides;
Xstruct IOExtTD *TDReq,
X	       *CreateExtIO();
Xchar	       *Device;
X
Xint
Xtodigit(c)
Xregister char	c;
X{
X    if ((c -= '0') < 0 || c > ('F' - '0'))
X	return 42;
X
X    if (c >= ('A' - '0')) {
X	c -= 'A' - '9' - 1;
X    }
X    return c;
X}
X
Xlong
Xntoi(str)
Xregister char  *str;
X{
X    register long   total = 0;
X    register long   value;
X    register int    digit;
X    register int    base;
X
X    /* First determine the base */
Xnumber:
X    if (*str == '0') {
X	if (*++str == 'x') {    /* 0x means hexadecimal */
X	    base = 16;
X	    str++;
X	} else {
X	    base = 8;		/* Otherwise, 0 means octal */
X	}
X    } else {
X	base = 10;		/* and any other digit means decimal */
X    }
X
X    value = 0;
X    while ((digit = todigit(*str)) < base) {
X	value *= base;
X	value += digit;
X	str++;
X    }
X
Xsuffix:
X    switch (*str++) {
X    case 'm':                   /* scale with megabytes */
X	value *= 1024L * 1024;
X	goto suffix;
X    case 'k':                   /* scale with kilobytes */
X	value *= 1024;
X	goto suffix;
X    case 's':                   /* scale with sectors */
X	value *= TD_SECTOR;	/* or maybe even kilosectors! */
X	goto suffix;
X    case 'b':                   /* scale with bytes */
X	goto suffix;
X    }
X    str--;
X
X    total += value;
X
X    if (*str >= '0' && *str <= '9')
X	goto number;		/* Allow 10k512, recursion eliminated */
X
X    return total;
X}
X
Xword
Xinput(question, defval)
Xchar	       *question;
Xword		defval;
X{
X    char	    buf[80];
X
X    printf("%s? [%d] ", question, defval);
X    fflush(stdout);
X    if (fgets(buf, sizeof (buf) - 1, stdin)) {
X	if (buf[0] && buf[0] != '\n')
X	    defval = ntoi(buf);
X    }
X    return defval;
X}
X
Xvoid
XPutWord(address, value)
Xregister byte  *address;
Xregister word	value;
X{
X    address[0] = value;
X    address[1] = value >> 8;
X}
X
Xword
XSetWord(address, question, value)
Xbyte	       *address;
Xchar	       *question;
Xword		value;
X{
X    value = input(question, value);
X    PutWord(address, value);
X
X    return value;
X}
X
Xbyte
XSetByte(address, question, value)
Xbyte	       *address;
Xchar	       *question;
Xword		value;
X{
X    value = input(question, value);
X    return *address = value;
X}
X
Xbyte	       *
XMaybeWrite(block)
Xbyte	       *block;
X{
X    while (block >= (DiskTrack + TrackSize)) {
X	int		t,
X			s;
X
X	t = Track / nsides;
X	s = Track % nsides;
X	printf("  Writing cylinder %3d side %d...\r", t, s);
X	fflush(stdout);
X	TDReq->iotd_Req.io_Command = TD_FORMAT;
X	TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
X	TDReq->iotd_Req.io_Length = TrackSize;
X	TDReq->iotd_Req.io_Offset = TrackSize * Track;
X	DoIO(TDReq);
X	if (TDReq->iotd_Req.io_Error) {
X	    printf(" Write error %d on cylinder %d side %d.\n",
X		   TDReq->iotd_Req.io_Error, t, s);
X	}
X	TDReq->iotd_Req.io_Command = CMD_UPDATE;
X	DoIO(TDReq);
X	if (TDReq->iotd_Req.io_Error) {
X	    printf("Update error %d on cylinder %d side %d.\n",
X		   TDReq->iotd_Req.io_Error, t, s);
X	}
X	TDReq->iotd_Req.io_Command = CMD_CLEAR;
X	DoIO(TDReq);
X
X	printf("  Read\r");
X	fflush(stdout);
X	TDReq->iotd_Req.io_Command = CMD_READ;
X	TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
X	TDReq->iotd_Req.io_Length = TrackSize;
X	TDReq->iotd_Req.io_Offset = TrackSize * Track;
X	DoIO(TDReq);
X	if (TDReq->iotd_Req.io_Error) {
X	    printf("  Read error %d on cylinder %d side %d.\n",
X		   TDReq->iotd_Req.io_Error, t, s);
X	}
X	setmem(DiskTrack, (int) TrackSize, 0);
X	Track++;
X	if ((block -= TrackSize) < DiskTrack)
X	    block = DiskTrack;
X    }
X    return block;
X}
X
Xmain(argc, argv)
Xint		argc;
Xchar	      **argv;
X{
X    struct MsgPort *port,
X		   *CreatePort();
X    byte	   *diskBlock;
X    long	    unitNr;
X    int 	    i;
X    word	    bps = MS_BPS,
X		    spt = MS_SPT;
X    word	    res,
X		    nfats,
X		    spf,
X		    nsects,
X		    ncylinders,
X		    ndirs,
X		    wholeDisk,
X		    clearFat,
X		    endtrack;
X
X    if (argc < 2) {
X	printf("Usage: %s <unitnr> <device>\n"
X	       "Formats a messydos volume in any desired shape.\n",
X	       argv[0]);
X	exit(1);
X    }
X    Enable_Abort = 0;
X    unitNr = ntoi(argv[1]);
X    if (argc > 2)
X	Device = argv[2];
X    else
X	Device = "messydisk.device";
X
X    if (!(port = CreatePort(NULL, 0L))) {
X	puts("No memory for replyport");
X	goto abort1;
X    }
X    if (!(TDReq = CreateExtIO(port, (long) sizeof (*TDReq)))) {
X	puts("No memory for I/O request");
X	goto abort2;
X    }
X    if (OpenDevice(Device, unitNr, TDReq, 0L)) {
X	printf("Cannot OpenDevice %s\n", Device);
X	goto abort3;
X    }
X
X    printf("Preparing to format disk in %s unit #%d.\n\n", Device, (int) unitNr);
X    bps = input("Bytes per sector", bps);
X    spt = input("Sectors per track", spt);
X    TrackSize = bps * spt;
X    nsides = input("Number of sides", MS_NSIDES);
X    Track = input("Starting cylinder", 0);
X    Track *= nsides;
X    ncylinders = input("Number of cylinders", 80);
X    endtrack = Track + nsides * ncylinders;
X
X    if ((DiskTrack = AllocMem(TrackSize,
X			MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR)) == NULL) {
X	puts("No memory for track buffer");
X	goto abort4;
X    }
X    CopyMem(BootBlock, DiskTrack, (long) sizeof (BootBlock));
X
X    PutWord(DiskTrack + 0x0b, bps);
X    SetByte(DiskTrack + 0x0d, "Sectors per cluster", MS_SPC);
X    res = SetWord(DiskTrack + 0x0e, "Bootsectors", MS_RES);
X    nfats = SetByte(DiskTrack + 0x10, "Number of FAT copies", MS_NFATS);
X    ndirs = SetWord(DiskTrack + 0x11, "Root directory entries", MS_NDIRS);
X    nsects = SetWord(DiskTrack + 0x13, "Total number of sectors", spt * ncylinders * nsides);
X    SetByte(DiskTrack + 0x15, "Media byte", 0xF9);
X    spf = SetWord(DiskTrack + 0x16, "Sectors per FAT", MS_SPF);
X    PutWord(DiskTrack + 0x18, spt);
X    PutWord(DiskTrack + 0x1a, nsides);
X    SetWord(DiskTrack + 0x1c, "Number of hidden sectors", 0);
X
X    wholeDisk = input("Format whole disk (enter 1)", 0);
X    if (!wholeDisk)
X	clearFat = input("Write how much then?\n"
X			 " (enter 0 for just the bootblock)\n"
X			 " (enter 1 for FAT and root directory as well)", 0);
X
X    if (input("Are you sure? (enter 42)", 0) != 42)
X	goto abort5;
X
X    if (Chk_Abort())
X	goto abort5;
X
X    if (!wholeDisk && !clearFat) {
X	puts("Writing bootblock only.");
X	TDReq->iotd_Req.io_Command = CMD_WRITE;
X	TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
X	TDReq->iotd_Req.io_Length = sizeof (BootBlock);
X	TDReq->iotd_Req.io_Offset = 0;
X	DoIO(TDReq);
X	TDReq->iotd_Req.io_Command = CMD_UPDATE;
X	DoIO(TDReq);
X
X	goto done;
X    }
X
X    /* Go to first FAT */
X    diskBlock = MaybeWrite(DiskTrack + bps * res);
X    for (i = 0; i < nfats; i++) {
X	diskBlock[0] = 0xF9;
X	diskBlock[1] = 0xFF;
X	diskBlock[2] = 0xFF;
X	diskBlock = MaybeWrite(diskBlock + bps * spf);  /* Next FAT */
X    }
X
X    /* Clear entire directory */
X    diskBlock = MaybeWrite(diskBlock + ndirs * MS_DIRENTSIZE);
X    MaybeWrite(DiskTrack + TrackSize);  /* Force a write */
X
X    ncylinders *= nsides;
X    if (wholeDisk) {
X	while (Track < ncylinders) {
X	    MaybeWrite(DiskTrack + TrackSize);  /* Write an empty track */
X	    if (Chk_Abort())
X		break;
X	}
X    }
X
Xdone:
X    TDReq->iotd_Req.io_Command = TD_MOTOR;
X    TDReq->iotd_Req.io_Length = 0;
X    DoIO(TDReq);
X
X    printf("\n\nNow remove the disk from the drive (or use DiskChange).\n");
X
Xabort5:
X    FreeMem(DiskTrack, TrackSize);
Xabort4:
X    CloseDevice(TDReq);
Xabort3:
X    DeleteExtIO(TDReq);
Xabort2:
X    DeletePort(port);
Xabort1:;
X
X}
X
X_wb_parse()
X{
X}
END_OF_FILE
if test 9671 -ne `wc -c <'src/messyfmt.c'`; then
    echo shar: \"'src/messyfmt.c'\" unpacked with wrong size!
fi
# end of 'src/messyfmt.c'
fi
if test -f 'src/support.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/support.c'\"
else
echo shar: Extracting \"'src/support.c'\" \(3812 characters\)
sed "s/^X//" >'src/support.c' <<'END_OF_FILE'
X/*-
X * $Id: support.c,v 1.30 90/06/04 23:16:41 Rhialto Rel $
X * $Log:	support.c,v $
X * Revision 1.30  90/06/04  23:16:41  Rhialto
X * Release 1 Patch 3
X * 
X-*/
X
X#include "dos.h"
X
Xextern PORT    *DosPort;	/* Our DOS port... */
X
Xtypedef unsigned long		ulong;
Xtypedef unsigned char		ubyte;
X
X/*
X * PACKET ROUTINES.	Dos Packets are in a rather strange format as you
X * can see by this and how the PACKET structure is extracted in the
X * GetMsg() of the main routine.
X */
X
Xvoid
Xreturnpacket(packet)
Xregister struct DosPacket *packet;
X{
X    register struct Message *mess;
X    register struct MsgPort *replyport;
X
X    replyport = packet->dp_Port;
X    mess = packet->dp_Link;
X    packet->dp_Port = DosPort;
X    mess->mn_Node.ln_Name = (char *) packet;
X    mess->mn_Node.ln_Succ = NULL;
X    mess->mn_Node.ln_Pred = NULL;
X    PutMsg(replyport, mess);
X}
X
X/*
X * Are there any packets queued to our device?
X */
X
Xint
Xpacketsqueued()
X{
X    return ((void *) DosPort->mp_MsgList.lh_Head !=
X	    (void *) &DosPort->mp_MsgList.lh_Tail);     /* & inserted by OIS */
X}
X
X/*
X * DOS MEMORY ROUTINES
X */
X
Xvoid	       *
Xdosalloc(bytes)
Xregister ulong	bytes;
X{
X    register ulong *ptr;
X
X    bytes += sizeof (*ptr);
X    if (ptr = AllocMem(bytes, MEMF_PUBLIC | MEMF_CLEAR)) {
X	*ptr = bytes;
X	return (ptr + 1);
X    }
X
X    return NULL;
X}
X
Xdosfree(ptr)
Xregister ulong *ptr;
X{
X    --ptr;
X    FreeMem(ptr, *ptr);
X}
X
X/*
X * Convert a BSTR into a normal string.. copying the string into buf. I
X * use normal strings for internal storage, and convert back and forth
X * when required.
X */
X
Xvoid
Xbtos(bstr, buf)
Xubyte	       *bstr;
Xubyte	       *buf;
X{
X    bstr = BTOC(bstr);
X    bmov(bstr + 1, buf, *bstr);
X    buf[*bstr] = 0;
X}
X
X/*
X * Some EXEC list handling routines not found in the EXEC library.
X */
X
X#ifdef notdef
X
Xvoid	       *
XNextNode(node)
Xregister NODE		*node;
X{
X    node = node->mln_Succ;
X    if (node->mln_Succ == NULL)
X	return (NULL);
X    return (node);
X}
X
X#endif
X
Xvoid	       *
XGetHead(list)
Xregister LIST		*list;
X{
X    if ((void *) list->mlh_Head != (void *) &list->mlh_Tail)
X	return (list->mlh_Head);
X    return (NULL);
X}
X
Xvoid	       *
XGetTail(list)
Xregister LIST		*list;
X{
X    if ((void *) list->mlh_Head != (void *) &list->mlh_Tail)
X	return (list->mlh_TailPred);
X    return (NULL);
X}
X
X#ifdef HDEBUG
Xchar	       *
Xtypetostr(ty)
Xlong ty;
X{
X    switch (ty) {
X    case ACTION_DIE:
X	return ("DIE");
X    case ACTION_CURRENT_VOLUME:
X	return ("CURRENT VOLUME");
X    case ACTION_OPENRW:
X	return ("OPEN-RW");
X    case ACTION_OPENOLD:
X	return ("OPEN-OLD");
X    case ACTION_OPENNEW:
X	return ("OPEN-NEW");
X    case ACTION_READ:
X	return ("READ");
X    case ACTION_WRITE:
X	return ("WRITE");
X    case ACTION_CLOSE:
X	return ("CLOSE");
X    case ACTION_SEEK:
X	return ("SEEK");
X    case ACTION_EXAMINE_NEXT:
X	return ("EXAMINE NEXT");
X    case ACTION_EXAMINE_OBJECT:
X	return ("EXAMINE OBJ");
X    case ACTION_INFO:
X	return ("INFO");
X    case ACTION_DISK_INFO:
X	return ("DISK INFO");
X    case ACTION_PARENT:
X	return ("PARENTDIR");
X    case ACTION_DELETE_OBJECT:
X	return ("DELETE");
X    case ACTION_CREATE_DIR:
X	return ("CREATEDIR");
X    case ACTION_LOCATE_OBJECT:
X	return ("LOCK");
X    case ACTION_COPY_DIR:
X	return ("DUPLOCK");
X    case ACTION_FREE_LOCK:
X	return ("FREELOCK");
X    case ACTION_SET_PROTECT:
X	return ("SETPROTECT");
X    case ACTION_SET_COMMENT:
X	return ("SETCOMMENT");
X    case ACTION_RENAME_OBJECT:
X	return ("RENAME");
X    case ACTION_INHIBIT:
X	return ("INHIBIT");
X    case ACTION_RENAME_DISK:
X	return ("RENAME DISK");
X    case ACTION_MORECACHE:
X	return ("MORE CACHE");
X    case ACTION_WAIT_CHAR:
X	return ("WAIT FOR CHAR");
X    case ACTION_FLUSH:
X	return ("FLUSH");
X    case ACTION_RAWMODE:
X	return ("RAWMODE");
X    case ACTION_SET_DATE:
X	return ("SET_DATE");
X    default:
X	return ("---------UNKNOWN-------");
X    }
X}
X
X#endif				/* HDEBUG */
END_OF_FILE
if test 3812 -ne `wc -c <'src/support.c'`; then
    echo shar: \"'src/support.c'\" unpacked with wrong size!
fi
# end of 'src/support.c'
fi
echo shar: End of archive 1 \(of 6\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general discussion to comp.sys.amiga.