executor/src/diskinit.c

257 lines
5.3 KiB
C

/* Copyright 1986, 1988, 1989, 1990 by Abacus Research and
* Development, Inc. All rights reserved.
*/
#if !defined (OMIT_RCSID_STRINGS)
char ROMlib_rcsid_diskinit[] =
"$Id: diskinit.c 87 2005-05-25 01:57:33Z ctm $";
#endif
/* Forward declarations in DiskInit.h (DO NOT DELETE THIS LINE) */
#include "rsys/common.h"
#include "MemoryMgr.h"
#include "FileMgr.h"
#include "OSUtil.h"
#include "rsys/common.h"
#include "DiskInit.h"
#include "rsys/glue.h"
#include "mkvol/mkvol.h"
#include "rsys/hfs.h"
#include "rsys/blockinterrupts.h"
P0(PUBLIC pascal trap, void, DILoad)
{
}
P0(PUBLIC pascal trap, void, DIUnload)
{
}
P2(PUBLIC pascal trap, INTEGER, DIBadMount, Point, pt, LONGINT, evtmess)
{
return paramErr;
}
P1(PUBLIC pascal trap, OSErr, DIFormat, INTEGER, dn)
{
return noErr; /* We don't do low-level formats right now */
}
enum
{
FLOPPY_SIDES_PER_DISK = 2,
FLOPPY_TRACKS_PER_SIDE = 80,
FLOPPY_SECTORS_PER_TRACK = 18,
FLOPPY_SECTORS_PER_DISK = FLOPPY_SIDES_PER_DISK * FLOPPY_TRACKS_PER_SIDE
* FLOPPY_SECTORS_PER_TRACK,
};
PRIVATE OSErr
get_vref_dref (INTEGER rn, INTEGER *vrefp, INTEGER *drefp)
{
OSErr retval;
retval = noErr;
*vrefp = rn;
*drefp = OURHFSDREF;
return retval;
}
typedef struct {
INTEGER vref;
INTEGER dref;
LONGINT pos;
} our_file_info_t;
typedef OSErrRET (*func_t) (ParmBlkPtr pb, BOOLEAN async);
PRIVATE OSErr
raw_read_write (func_t func, our_file_info_t *op, LONGINT *lengthp,
char buf[])
{
OSErr retval;
ParamBlockRec pbr;
check_virtual_interrupt ();
pbr.ioParam.ioVRefNum = CW (op->vref);
pbr.ioParam.ioRefNum = CW (op->dref);
pbr.ioParam.ioBuffer = (Ptr) RM (buf);
pbr.ioParam.ioReqCount = CL (*lengthp);
pbr.ioParam.ioPosMode = CWC (fsFromStart);
pbr.ioParam.ioPosOffset = CL (op->pos);
retval = func (&pbr, FALSE);
if (retval == noErr)
{
*lengthp = CL (pbr.ioParam.ioActCount);
op->pos += CL (pbr.ioParam.ioActCount);
}
return retval;
}
PRIVATE OSErr
raw_read (our_file_info_t *op, LONGINT *lengthp, char buf[])
{
return raw_read_write (PBRead, op, lengthp, buf);
}
PRIVATE OSErr
raw_write (our_file_info_t *op, LONGINT *lengthp, char buf[])
{
return raw_read_write (PBWrite, op, lengthp, buf);
}
enum { N_TRACK_BYTES = (PHYSBSIZE * FLOPPY_SIDES_PER_DISK
* FLOPPY_SECTORS_PER_TRACK) };
P1(PUBLIC pascal trap, OSErr, DIVerify, INTEGER, dn)
{
int i;
char buf[N_TRACK_BYTES];
LONGINT length;
OSErr err;
our_file_info_t oi;
err = get_vref_dref (dn, &oi.vref, &oi.dref);
oi.pos = 0;
if (err == noErr)
{
for (i = 0, err = noErr; err == noErr && i < FLOPPY_TRACKS_PER_SIDE; ++i)
{
length = sizeof(buf);
err = raw_read (&oi, &length, buf);
if (err == noErr && length != sizeof(buf))
err = ioErr;
}
}
return err;
}
/*
* NOTE: This track at a time buffering will only work if there are no
* gaps in the data that is being written. Currently, that's how
* we format floppies, but eventually we need something better here.
*/
PRIVATE Ptr track_bufp;
PRIVATE long offset;
PRIVATE long length;
PRIVATE OSErr
begin_track_buffering_for_write (void)
{
OSErr retval;
track_bufp = NewPtr (N_TRACK_BYTES);
if (track_bufp)
{
retval = noErr;
offset = 0;
length = 0;
}
else
retval = MemErr;
return retval;
}
PRIVATE OSErr
flush_buffer (our_file_info_t *ofitp)
{
OSErr retval;
LONGINT n_to_write;
n_to_write = length;
retval = raw_write (ofitp, &n_to_write, (char *) track_bufp);
if (retval == noErr && n_to_write != length)
retval = ioErr;
else
{
length = 0;
offset += n_to_write;
}
return retval;
}
PRIVATE size_t
writefunc (int magic, void *buf, size_t buf_len)
{
OSErr err;
our_file_info_t *ofip;
char *bufp;
size_t buf_len_remaining;
buf_len_remaining = buf_len;
ofip = (our_file_info_t *) magic;
if (ofip->pos != offset)
warning_unexpected ("ofip->pos = %d, offset = %ld\n", ofip->pos, offset);
bufp = buf;
err = noErr;
while (err == noErr && buf_len_remaining > 0)
{
uint32 n_bytes_left, n_to_copy;
n_bytes_left = N_TRACK_BYTES - length;
n_to_copy = MIN (n_bytes_left, buf_len_remaining);
memcpy (track_bufp + length, bufp, n_to_copy);
length += n_to_copy;
if (length == N_TRACK_BYTES)
err = flush_buffer(ofip);
buf_len_remaining -= n_to_copy;
}
return err ? 0 : buf_len;
}
PRIVATE OSErr
end_track_buffering_for_write (our_file_info_t *ofitp)
{
OSErr retval;
if (length)
retval = flush_buffer (ofitp);
else
retval = noErr;
DisposPtr (track_bufp);
track_bufp = 0;
return retval;
}
/*
* Hacky -- assumes 1.4 MB, but it's a start
*/
P2(PUBLIC pascal trap, OSErr, DIZero, INTEGER, dn, StringPtr, vname)
{
OSErr err;
LONGINT time;
int name_len;
char *name;
our_file_info_t oi;
name_len = vname[0];
name = alloca(name_len + 1);
memcpy(name, vname+1, name_len);
name[name_len] = 0;
GetDateTime(&time);
err = get_vref_dref (dn, &oi.vref, &oi.dref);
if (err == noErr)
{
oi.pos = 0;
err = begin_track_buffering_for_write ();
if (err == noErr)
{
OSErr err2;
err = format_disk(time, name, FLOPPY_SECTORS_PER_DISK, writefunc,
(int) &oi);
err2 = end_track_buffering_for_write (&oi);
if (err == noErr)
err = err2;
}
}
return err;
}