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.