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

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (02/21/90)

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

[ The doc files doc/msh.man and doc/dev.man have been uuencoded because 
  they contain ANSI-style highlighting.  ...tad ]

It is my Messydos File System Handler, or MSH for short. This will
probably be the end of CrossDos, and certainly be the end of
Dos-2-Dos, since this is a fully functional, read/write version, which
also includes source. It supports 8, 9 or 10 sector disks of 80
tracks, and should also work on 40 track drives and hard disks.
(untested).

Freely_Distributable=Greetings(Not_For_Any_Commercial_Purpose)->
        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:  devs devs/Mountlist doc doc/RELEASE-NOTES src src/Makefile
#   src/date.c src/dev.h src/device.h src/die.c src/dos.h src/han.h
#   src/hanreq.c src/ignore.c src/messyfmt.c src/support.c
# Wrapped by tadguy@xanth on Tue Feb 20 20:57:06 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'devs' ; then
    echo shar: Creating directory \"'devs'\"
    mkdir 'devs'
fi
if test -f 'devs/Mountlist' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'devs/Mountlist'\"
else
echo shar: Extracting \"'devs/Mountlist'\" \(1505 characters\)
sed "s/^X//" >'devs/Mountlist' <<'END_OF_FILE'
X/*
X *  This Mountlist is just an example. Edit the locations of
X *  messydisk.device and MessyFileSystem appropriately.
X/* Messy file system on messy blocks: */
XMSH:	FileSystem = messydos:l/MessyFileSystem
X	Device = messydos:devs/messydisk.device
X	Unit = 1
X	Flags = 0
X	LowCyl = 0 ; HighCyl = 79
X	Surfaces = 2
X	BlocksPerTrack = 9
X	Buffers = 5
X	BufMemType = 1	/* messydisk needs no chip mem */
X	BootPri = 0
X	Stacksize = 4096
X	Priority = 5
X	GlobVec  = -1
X#
XMS2:	FileSystem = messydos:l/MessyFileSystem
X	Device = messydos:devs/messydisk.device
X	Unit = 2
X	Flags = 0
X	LowCyl = 0 ; HighCyl = 79
X	Surfaces = 2
X	BlocksPerTrack = 9
X	Buffers = 5
X	BufMemType = 1	/* messydisk needs no chip mem */
X	BootPri = 0
X	Stacksize = 4096
X	Priority = 5
X	GlobVec  = -1
X#
X/* Messy blocks mapped to a flat file: */
XRDF:	FileSystem = messydos:l/RDF-Handler
X	Device = messydos:devs/messydisk.device
X	Unit = 1
X	Flags = 0
X	Stacksize = 4096
X	Priority = 4
X	GlobVec  = -1
X#
X/* Amiga Old filing system on messy blocks: */
XMF1:	Device = messydos:devs/messydisk.device
X	Unit = 1
X	Flags = 0
X	Priority = 4
X	LowCyl = 0 ; HighCyl = 79
X	Reserved = 2
X	Surfaces = 2
X	BlocksPerTrack = 9
X	Buffers = 5
X	BufMemType = 1
X	BootPri = 0
X#
X/* Messy file system on Amiga blocks: */
XDS1:	FileSystem = messydos:l/MessyFileSystem
X	Device = trackdisk.device
X	Unit = 1
X	Flags = 0
X	LowCyl = 0 ; HighCyl = 79
X	Surfaces = 2
X	BlocksPerTrack = 11
X	Buffers = 5
X	BufMemType = 3	/* trackdisk needs CHIP mem */
X	BootPri = 0
X	Stacksize = 4096
X	Priority = 5
X	GlobVec  = -1
X#
END_OF_FILE
if test 1505 -ne `wc -c <'devs/Mountlist'`; then
    echo shar: \"'devs/Mountlist'\" unpacked with wrong size!
fi
# end of 'devs/Mountlist'
fi
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'\" \(2669 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                   11-Feb-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
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
X
END_OF_FILE
if test 2669 -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 ! -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'\" \(1452 characters\)
sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
X# $Id: Makefile,v 1.5 90/02/10 22:38:29 Rhialto Exp $
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 date.o
XHSRC =	pack.c support.c hanmain.c hansec.c hanlock.c hanfile.c hanreq.c date.c \
X	dos.h han.h
XDOBJ =	device.o devio.o
XDSRC =	device.c devio.c dev.h device.h
XXSRC =	messyfmt.c Makefile
X#DB =	 -DDEBUG
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:	msh messydisk.device
Xutils:	die ignore messyfmt
Xdoc:	dev.man msh.man
X
Xmessydisk.device: $(DOBJ)
X	ln -o $@ $(WACK) $(DOBJ) -lcl
X
Xmsh:	$(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: messyfmt.c dev.h device.h han.h
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
Xdevice.o: dev.h device.h
Xdevio.o: dev.h device.h
Xhanmain.o: han.h dev.h
Xhansec.o: han.h dev.h
Xhanlock.o: dos.h han.h dev.h
Xhanfile.o: dos.h han.h dev.h
Xsupport.o: dos.h
Xpack.o: dos.h han.h dev.h
END_OF_FILE
if test 1452 -ne `wc -c <'src/Makefile'`; then
    echo shar: \"'src/Makefile'\" unpacked with wrong size!
fi
# 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'\" \(3575 characters\)
sed "s/^X//" >'src/date.c' <<'END_OF_FILE'
X/*-
X * $Id: date.c,v 1.2 90/02/03 17:00:25 Rhialto Exp $
X * $Log:	date.c,v $
X * Revision 1.2  90/02/03  17:00:25  Rhialto
X * 0x21 -> DATE_MIN
X * 
X * Revision 1.1  89/12/17  20:03:37  Rhialto
X * Initial revision
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 3575 -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'\" \(602 characters\)
sed "s/^X//" >'src/dev.h' <<'END_OF_FILE'
X/*-
X *  $Id: dev.h,v 1.2 90/01/27 20:38:18 Rhialto Exp $
X *
X *  Include file for users of the messydisk.device
X-*/
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 602 -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'\" \(5272 characters\)
sed "s/^X//" >'src/device.h' <<'END_OF_FILE'
X/*-
X *  $Id: device.h,v 1.2 90/01/27 20:39:10 Rhialto Exp $
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	5
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   2048L
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 5272 -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'\" \(2369 characters\)
sed "s/^X//" >'src/dos.h' <<'END_OF_FILE'
X
X/*
X *  $Id: dos.h,v 1.2 90/01/27 20:29:53 Rhialto Exp $
X */
X
X#ifdef NOTDEF
X#include "exec/types.h"
X#include "exec/memory.h"
X#include "libraries/dos.h"
X#include "libraries/dosextens.h"
X#include "libraries/filehandler.h"
X#endif NOTDEF
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#define FIBB_HIDDEN 7L
X#define FIBF_HIDDEN (1L<<FIBB_HIDDEN)
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 2369 -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'\" \(8794 characters\)
sed "s/^X//" >'src/han.h' <<'END_OF_FILE'
X/*-
X *  $Id: han.h,v 1.4 90/01/27 20:33:22 Rhialto Exp $
X *
X *  The header file for the MESSYDOS: file system handler
X *
X-*/
X
X#include "dev.h"
X
X#define MODE_READWRITE	1004L
X#define MODE_CREATEFILE (1L<<31)
X#define FILE_DIR    1
X#define FILE_FILE   -1
X
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
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;	/* in 2s of seconds since begin of the day */
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();
X
X/*
X * PACK.C
X */
Xextern char *DevName;
Xextern long UnitNr;
Xextern ulong DevFlags;
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 * DATE.C
X */
Xextern void	ToDateStamp();
Xextern void	ToMSDate();
END_OF_FILE
if test 8794 -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/hanreq.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/hanreq.c'\"
else
echo shar: Extracting \"'src/hanreq.c'\" \(3036 characters\)
sed "s/^X//" >'src/hanreq.c' <<'END_OF_FILE'
X/*-
X * $Id: hanreq.c,v 1.1 89/12/17 20:03:24 Rhialto Exp Locker: Rhialto $
X * $Log:	hanreq.c,v $
X * Revision 1.1  89/12/17  20:03:24  Rhialto
X * Initial revision
X * 
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 <exec/io.h>
X#include <devices/trackdisk.h>
X#include <intuition/intuition.h>
X
X#ifdef DEBUG
X#   define	debug(x)  dbprintf x
X#else
X#   define	debug(x)
X#endif
X
Xstruct IntuiText Positive = {
X    AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X    AUTOLEFTEDGE, AUTOTOPEDGE, AUTOITEXTFONT,
X    (UBYTE *)"Retry",
X    AUTONEXTTEXT
X};
X
Xstruct IntuiText Negative = {
X    AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X    AUTOLEFTEDGE, AUTOTOPEDGE, AUTOITEXTFONT,
X    (UBYTE *)"Cancel",
X    AUTONEXTTEXT
X};
X
Xstruct 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 AutoRequest();
Xextern struct DosPacket *DosPacket;
Xextern struct DeviceList *VolNode;
Xextern short DiskChanged;
X
Xlong
XRetryRwError(req)
Xstruct IOExtTD *req;
X{
X    register struct Window *window;
X    struct MsgPort *port;
X    struct Process *proc;
X    struct IntuiText *text;
X    long result;
X
X    if (DosPacket != NULL) { /* A user-requested action */
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 = NULL;
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	if (DiskChanged == 0)   /* Cheating, huh ? */
X	    goto again;
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 3036 -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'\" \(8923 characters\)
sed "s/^X//" >'src/messyfmt.c' <<'END_OF_FILE'
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		    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    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 (input("Are you sure? (enter 42)", 0) != 42)
X	goto abort5;
X
X    if (Chk_Abort())
X	goto abort5;
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    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 8923 -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'\" \(3891 characters\)
sed "s/^X//" >'src/support.c' <<'END_OF_FILE'
X/*-
X * $Id: support.c,v 1.2 90/02/03 17:01:19 Rhialto Exp $
X * $Log:	support.c,v $
X * Revision 1.2  90/02/03  17:01:19  Rhialto
X * Add error checking in dosalloc()
X * 
X * Revision 1.1  89/12/17  19:57:50  Rhialto
X * Initial revision
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 DEBUG
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				/* DEBUG */
END_OF_FILE
if test 3891 -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.