afb@j.cc.purdue.edu (Matthew Bradburn) (12/19/87)
Here's the source to Matt Dillon's support library, which you
will need to compile DME, DTERM, etc. It would no doubt also
be useful for myriad other tasks.
Matthew Bradburn
afb@j.cc.purdue.edu (arpa)
j.cc.purdue.edu!afb (uucp)
bradburn@purccvm.bitnet (bitnet)
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# POSTER
# Makefile
# atoi.c
# break.c
# checkbreak.c
# closelibs.c
# dio.c
# llink.c
# lunlink.c
# mntreq.c
# openlibs.c
# resetbreak.c
# wildcmp.c
# xfio.c
# bcmp.asm
# bmov.asm
# bset.asm
# fhprintf.asm
# dio.h
# typedefs.h
# xmisc.h
# This archive created: Fri Dec 18 18:10:41 1987
# By: Matthew Bradburn (Purdue University)
echo shar: extracting POSTER '(687 characters)'
cat << \SHAR_EOF > POSTER
Return-Path: dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu
Received: from k.cc.purdue.edu by j.cc.purdue.edu (5.54/1.14)
id AA15508; Fri, 20 Nov 87 15:33:19 EST
Received: from j.cc.purdue.edu by k.cc.purdue.edu (5.54/1.14)
id AA07483; Fri, 20 Nov 87 15:32:24 EST
Received: by j.cc.purdue.edu (5.54/1.14)
id AA15322; Fri, 20 Nov 87 15:29:16 EST
Received: by cory.Berkeley.EDU (5.57/1.26)
id AA02857; Fri, 20 Nov 87 12:19:26 PST
Date: Fri, 20 Nov 87 12:19:26 PST
From: dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu (Matt Dillon)
Message-Id: <8711202019.AA02857@cory.Berkeley.EDU>
To: amiga-sources-request@j.cc.purdue.edu
Subject: SUPLIB SOURCE part 2 of 2
Precedence: special-delivery
SHAR_EOF
if test 687 -ne "`wc -c POSTER`"
then
echo shar: error transmitting POSTER '(should have been 687 characters)'
fi
echo shar: extracting Makefile '(1030 characters)'
cat << \SHAR_EOF > Makefile
# Aztec C makefile for my support lib, for use in DME, DTERM, and
# other programs I have written. NOTE: Some modification will be
# required as this is my personal makefile
OBJ1 = atoi.o checkbreak.o closelibs.o dio.o break.o
OBJ2 = llink.o lunlink.o mntreq.o openlibs.o resetbreak.o
OBJ3 = wildcmp.o bcmp.o bmov.o bset.o fhprintf.o xfio.o
SRC1 = atoi.c checkbreak.c closelibs.c dio.c break.c
SRC2 = llink.c lunlink.c mntreq.c openlibs.c resetbreak.c
SRC3 = wildcmp.c bcmp.asm bmov.asm bset.asm fhprintf.asm xfio.c
HDR = dio.h typedefs.h xmisc.h
CFLAGS = +BCDL +Ivd0:include/symbols.m
all: $(OBJ1) $(OBJ2) $(OBJ3)
shell -c echo *.o >ram:ordin
ord ram:ordin ram:ordout
lb ram:sup32.lib -f ram:ordout
copy ram:sup32.lib vd0:clib
delete ram:ordin ram:ordout ram:sup32.lib
clean:
-delete $(OBJ1)
-delete $(OBJ2)
-delete $(OBJ3)
arc:
-delete ram:suplib.arc
arc a ram:suplib vd0:clib/sup32.lib suplib.doc
arc a ram:suplib $(SRC1)
arc a ram:suplib $(SRC2)
arc a ram:suplib $(SRC3)
arc a ram:suplib $(HDR)
SHAR_EOF
if test 1030 -ne "`wc -c Makefile`"
then
echo shar: error transmitting Makefile '(should have been 1030 characters)'
fi
echo shar: extracting atoi.c '(345 characters)'
cat << \SHAR_EOF > atoi.c
/*
* atoi()
*
* Uses shifts instead of multiplies.
*/
long
atoi(str)
register char *str;
{
register long i = 0;
register long neg = 0;
while (*str == ' ')
++str;
if (*str == '-') {
++str;
neg = 1;
}
while (*str >= '0' && *str <= '9')
i = (i << 1) + (i << 3) + *str++ - '0';
return ((int)((neg)?-i:i));
}
SHAR_EOF
if test 345 -ne "`wc -c atoi.c`"
then
echo shar: error transmitting atoi.c '(should have been 345 characters)'
fi
echo shar: extracting break.c '(111 characters)'
cat << \SHAR_EOF > break.c
extern int Enable_Abort;
disablebreak()
{
Enable_Abort = 0;
}
enablebreak()
{
Enable_Abort = 1;
}
SHAR_EOF
if test 111 -ne "`wc -c break.c`"
then
echo shar: error transmitting break.c '(should have been 111 characters)'
fi
echo shar: extracting checkbreak.c '(153 characters)'
cat << \SHAR_EOF > checkbreak.c
/*
* CHECKBREAK()
*
* Return 1 = break pressed,
* 0 = break not pressed
*/
checkbreak()
{
return ((SetSignal(0,0)&SIGBREAKF_CTRL_C) != 0);
}
SHAR_EOF
if test 153 -ne "`wc -c checkbreak.c`"
then
echo shar: error transmitting checkbreak.c '(should have been 153 characters)'
fi
echo shar: extracting closelibs.c '(406 characters)'
cat << \SHAR_EOF > closelibs.c
/*
* CLOSELIBS(mask)
*
* Close the indicated libraries. Does not close libraries which
* have not been openned.
*/
#include "xmisc.h"
extern struct OLI strvar[];
closelibs(mask)
register unsigned short mask;
{
register struct OLI *sv;
for (sv = &strvar[0]; mask && sv->name; mask >>= 1, ++sv){
if ((mask & 1) && *sv->var) {
CloseLibrary(*sv->var);
*sv->var = 0L;
}
}
}
SHAR_EOF
if test 406 -ne "`wc -c closelibs.c`"
then
echo shar: error transmitting closelibs.c '(should have been 406 characters)'
fi
echo shar: extracting dio.c '(10969 characters)'
cat << \SHAR_EOF > dio.c
/*
* DIO.C
*
* (C)Copyright 1987 by Matthew Dillon, All rights reserved
* Freely distributable. Donations Welcome. This is NOT shareware,
* This is NOT public domain.
*
* Matthew Dillon
* 891 Regal Rd.
* Berkeley, Ca. 94708
*
* EXEC device driver IO support routines... makes everything easy.
*
* dfd = dio_open(name, unit, flags, req/NULL)
*
* open an IO device. Note: in some cases you might have to provide
* a request structure with some fields initialized (example, the
* console device requires certain fields to be initialized). For
* instance, if openning the SERIAL.DEVICE, you would want to give
* an IOExtSer structure which is completely blank execept for the
* io_SerFlags field.
*
* The request structure's message and reply ports need not be
* initialized. The request structure is no longer needed after
* the dio_open().
*
* NULL = error, else descriptor (a pointer) returned.
*
*
* dio_close(dfd)
*
* close an IO device. Any pending asyncronous requests are
* AbortIO()'d and then Wait'ed on for completion.
*
*
* dio_closegrp(dfd)
*
* close EVERY DIO DESCRIPTOR ASSOCIATED WITH THE dio_open() call
* that was the parent for this descriptor. That is, you can get
* a descriptor using dio_open(), dio_dup() it a couple of times,
* then use dio_closegrp() on any ONE of the resulting descriptors
* to close ALL of them.
*
*
* dio_ddl(dfd,bool)
*
* Disable BUF and LEN fields in dio_ctl[_to].. dummy parameters
* must still be passed, but they are not loaded into the io_Data
* and io_Length fields of the io request. This is for devices
* like the AUDIO.DEVICE which has io_Data/io_Length in non-standard
* places.
*
* dio_cact(dfd,bool)
*
* If an error occurs (io_Error field), the io_Actual field is usually
* not modified by the device driver, and thus contains garbage. To
* provide a cleaner interface, you can have DIO_CTL() and DIO_CTL_TO()
* calls automatically pre-clear this field so if an io_Error does
* occur, the field is a definate 0 instead of garbage.
*
* In most cases you will want to do this. An exception is the
* TIMER.DEVICE, which uses the io_Actual field for part of the
* timeout structure.
*
* This flags the particular dio descriptor to do the pre-clear, and
* any new descriptors obtained by DIO_DUP()ing this one will also
* have the pre-clear flag set.
*
*
* dio_dup(dfd)
*
* Returns a new channel descriptor referencing the same device.
* The new descriptor has it's own signal and IO request structure.
* For instance, if you openned the serial device, you might want
* to dup the descriptor so you can use one channel to pend an
* asyncronous read, and the other channel to write out to the device
* and do other things without disturbing the asyncronous read.
*
*
* sig = dio_signal(dfd)
*
* get the signal number (0..31) used for a DIO descriptor.
* This allows you to Wait() for asyncronous requests. Note that
* if your Wait() returns, you should double check using dio_isdone()
*
* dio_flags(dfd, or, ~and)
*
* Modify the io_Flags field in the request, ORing it with the OR
* mask, and ANDing it with ~AND mask. E.G., the AUDIO.DEVICE requires
* some flags be put in io_Flags.
*
* req = dio_ctl_to(dfd, command, buf, len, to)
*
* Same as DIO_CTL() below, but (A) is always syncronous, and
* (B) will attempt to AbortIO()+WaitIO() the request if the
* timeout occurs before the IO completes.
*
* the 'to' argument is in microseconds.
*
* If timeout occurs before request completes, and DIO aborts the
* request, some devices do not have the io_Actual field set
* properly.
*
* req = dio_ctl(dfd, command, buf, len)
*
* DIO_CTL() is the basis for the entire library. It works as follows:
*
* (1) If the channel isn't clear (there is an asyncronous IO request
* still pending), DIO_CTL() waits for it to complete
*
* (2) If the command is 0, simply return a pointer to the io
* request structure.
*
* (3) If the DIO_CACT() flag is TRUE, the io_Actual field of the
* request is cleared.
*
* (4) Set the io_Data field to 'buf', and io_Length field to 'len'
* If the command is positive, use DoIO(). If the command
* negative, take it's absolute value and then do a SendIO().
* (The command is placed in the io_Command field, of course).
*
* (5) return the IO request structure
*
*
* bool= dio_isdone(dfd)
*
* return 1 if current channel is clear (done processing), else 0.
* e.g. if you did, say, an asyncronous read, and dio_isdone() returns
* true, you can now use the data buffer returned and look at the
* io_Actual field.
*
* You need not do a dio_wait() after dio_isdone() returns 1.
*
*
* req = dio_wait(dfd)
*
* Wait on the current channel for the request to complete and
* then return the request structure. (nop if channel is clear)
*
*
* req = dio_abort(dfd)
*
* Abort the request on the current channel (nop if channel is
* clear). Sends an AbortIO() if the channel is active and then
* WaitIO()'s the request.
*
*
* MACROS: SEE DIO.H
*
*/
#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <devices/timer.h>
#include "xmisc.h"
#define MPC (MEMF_CLEAR|MEMF_PUBLIC)
#define CPORT ior.ior.io_Message.mn_ReplyPort
#define MAXREQSIZE 128 /* big enough to hold all Amiga iorequests */
typedef struct IORequest IOR;
typedef struct IOStdReq STD;
typedef struct MsgPort PORT;
typedef struct {
STD ior;
char filler[MAXREQSIZE-sizeof(STD)];
} MAXIOR;
typedef struct {
struct _CHAN *list;
short refs;
} DIO;
typedef struct _CHAN {
MAXIOR ior;
DIO *base;
XLIST link; /* doubly linked list */
STD timer;
char notclear;
char cact; /* automatic io_Actual field clear */
char ddl;
UBYTE flagmask;
} CHAN;
extern CHAN *dio_ctl(), *dio_ctl_to(), *dio_wait(), *dio_abort();
extern PORT *CreatePort();
extern char *AllocMem();
CHAN *
dio_open(name, unit, flags, req)
char *name;
MAXIOR *req; /* not really this big */
{
register CHAN *chan;
register DIO *dio;
register PORT *port;
int ret;
dio = (DIO *)AllocMem(sizeof(DIO), MPC); if (!dio) goto fail3;
chan= (CHAN *)AllocMem(sizeof(CHAN), MPC); if (!chan) goto fail2;
if (req)
chan->ior = *req;
chan->CPORT = CreatePort(NULL,0); if (!chan->CPORT) goto fail1;
chan->ior.ior.io_Message.mn_Node.ln_Type = NT_MESSAGE;
chan->base = dio;
chan->flagmask = 0xF0;
dio->refs = 1;
if (OpenDevice(name, unit, &chan->ior, flags)) {
DeletePort(chan->CPORT);
fail1: FreeMem(chan, sizeof(CHAN));
fail2: FreeMem(dio, sizeof(DIO));
fail3: return(NULL);
}
llink(&dio->list, &chan->link);
chan->ior.ior.io_Flags = 0;
return(chan);
}
void
dio_dfm(chan,mask)
CHAN *chan;
{
chan->flagmask = mask;
}
void
dio_ddl(chan,n)
CHAN *chan;
{
chan->ddl = n;
}
void
dio_cact(chan,n)
CHAN *chan;
{
chan->cact = n;
}
void
dio_close(chan)
register CHAN *chan;
{
dio_abort(chan);
lunlink(&chan->link);
if (--chan->base->refs == 0) {
FreeMem(chan->base, sizeof(DIO));
CloseDevice(&chan->ior);
}
if (chan->timer.io_Message.mn_ReplyPort)
CloseDevice(&chan->timer);
DeletePort(chan->CPORT);
FreeMem(chan, sizeof(CHAN));
}
void
dio_closegroup(chan)
register CHAN *chan;
{
register CHAN *nextc;
for (chan = chan->base->list; chan; chan = nextc) {
chan = (CHAN *)((char *)chan - ((char *)&chan->link - (char *)chan));
nextc = (CHAN *)chan->link.next;
dio_close(chan);
}
}
CHAN *
dio_dup(chan)
register CHAN *chan;
{
register CHAN *nc;
if (chan) {
nc = (CHAN *)AllocMem(sizeof(CHAN), MPC); if (!nc) goto fail2;
nc->ior = chan->ior;
nc->base = chan->base;
nc->CPORT = CreatePort(NULL,0); if (!nc->CPORT) goto fail1;
nc->ior.ior.io_Flags = NULL;
nc->cact = chan->cact;
nc->ddl = chan->ddl;
nc->flagmask = chan->flagmask;
++nc->base->refs;
llink(&nc->base->list, &nc->link);
return(nc);
fail1: FreeMem(nc, sizeof(CHAN));
}
fail2:
return(NULL);
}
dio_signal(chan)
CHAN *chan;
{
return(chan->CPORT->mp_SigBit);
}
dio_flags(chan,or,and)
long chan;
{
IOR *ior = (void *)chan;
ior->io_Flags = (ior->io_Flags | or) & ~and;
}
CHAN *
dio_ctl_to(chan, com, buf, len, to)
register CHAN *chan;
char *buf;
{
register long mask;
if (chan->timer.io_Message.mn_ReplyPort == NULL) {
chan->timer.io_Message.mn_ReplyPort = chan->CPORT;
chan->timer.io_Message.mn_Node.ln_Type = NT_MESSAGE;
if (OpenDevice("timer.device", UNIT_VBLANK, &chan->timer, 0)) {
puts("Panic: DIO_CTL_TO: No timer.device");
}
chan->timer.io_Command = TR_ADDREQUEST;
}
mask = 1 << chan->CPORT->mp_SigBit;
dio_ctl(chan, (com>0)?-com:com, buf, len); /* SendIO the request */
chan->timer.io_Actual = to / 1000000;
chan->timer.io_Length = to % 1000000; /* setup timer */
chan->timer.io_Flags = 0;
BeginIO(&chan->timer); /* start timer running */
while (Wait(mask)) { /* Wait for something */
if (CheckIO(chan)) /* request done */
break;
if (CheckIO(&chan->timer)) { /* timeout? */
dio_abort(chan);
break;
}
}
AbortIO(&chan->timer); /* kill the timer */
WaitIO(&chan->timer); /* remove from rp */
return(chan); /* return ior */
}
CHAN *
dio_ctl(chan, com, buf, len)
register CHAN *chan;
char *buf;
{
if (chan->notclear) { /* wait previous req to finish */
WaitIO(chan);
chan->notclear = 0;
}
if (com) {
if (chan->cact)
chan->ior.ior.io_Actual = 0; /* initialize io_Actual to 0*/
chan->ior.ior.io_Error = 0; /* initialize error to 0 */
if (!chan->ddl) {
chan->ior.ior.io_Data = (APTR)buf; /* buffer */
chan->ior.ior.io_Length = len; /* length */
}
if (com < 0) { /* asyncronous IO */
chan->ior.ior.io_Command = -com;
chan->notclear = 1;
chan->ior.ior.io_Flags &= chan->flagmask;
BeginIO(chan);
} else { /* syncronous IO */
chan->ior.ior.io_Command = com;
chan->ior.ior.io_Flags = (chan->ior.ior.io_Flags & chan->flagmask) | IOF_QUICK;
BeginIO(chan);
if (!(chan->ior.ior.io_Flags & IOF_QUICK))
WaitIO(chan);
}
}
return(chan);
}
CHAN *
dio_isdone(chan)
register CHAN *chan;
{
if (chan->notclear) { /* if not clear */
if (CheckIO(chan)) { /* if done */
WaitIO(chan); /* clear */
chan->notclear = 0;
return(chan); /* done */
}
return(NULL); /* notdone */
}
return(chan); /* done */
}
CHAN *
dio_wait(chan)
register CHAN *chan;
{
if (chan->notclear) {
WaitIO(chan); /* wait and remove from rp */
chan->notclear = 0;
}
return(chan);
}
CHAN *
dio_abort(chan)
register CHAN *chan;
{
if (chan->notclear) {
AbortIO(chan); /* Abort it */
WaitIO(chan); /* wait and remove from rp */
chan->notclear = 0;
}
return(chan);
}
SHAR_EOF
if test 10969 -ne "`wc -c dio.c`"
then
echo shar: error transmitting dio.c '(should have been 10969 characters)'
fi
echo shar: extracting llink.c '(200 characters)'
cat << \SHAR_EOF > llink.c
#include "xmisc.h"
XLIST *
llink(list, en)
register XLIST *en, **list;
{
en->next = *list;
en->prev = list;
*list = en;
if (en->next)
en->next->prev = &en->next;
return(en);
}
SHAR_EOF
if test 200 -ne "`wc -c llink.c`"
then
echo shar: error transmitting llink.c '(should have been 200 characters)'
fi
echo shar: extracting lunlink.c '(210 characters)'
cat << \SHAR_EOF > lunlink.c
#include "xmisc.h"
XLIST *
lunlink(en)
register XLIST *en;
{
if (en) {
if (en->next)
en->next->prev = en->prev;
*en->prev = en->next;
en->next = NULL;
en->prev = NULL;
}
return(en);
}
SHAR_EOF
if test 210 -ne "`wc -c lunlink.c`"
then
echo shar: error transmitting lunlink.c '(should have been 210 characters)'
fi
echo shar: extracting mntreq.c '(388 characters)'
cat << \SHAR_EOF > mntreq.c
extern struct Process *FindTask();
mountrequest(bool)
{
static APTR original_pr_WindowPtr;
register struct Process *proc;
proc = FindTask(0);
if (!bool && proc->pr_WindowPtr != (APTR)-1) {
original_pr_WindowPtr = proc->pr_WindowPtr;
proc->pr_WindowPtr = (APTR)-1;
}
if (bool && proc->pr_WindowPtr == (APTR)-1)
proc->pr_WindowPtr = original_pr_WindowPtr;
}
SHAR_EOF
if test 388 -ne "`wc -c mntreq.c`"
then
echo shar: error transmitting mntreq.c '(should have been 388 characters)'
fi
echo shar: extracting openlibs.c '(1418 characters)'
cat << \SHAR_EOF > openlibs.c
#include "xmisc.h"
long GfxBase;
long IntuitionBase;
long ExpansionBase;
long DiskfontBase;
long TranslatorBase;
long IconBase;
long MathBase;
long MathTransBase;
long MathIeeeDoubBasBase;
long MathIeeeSingBasBase;
long LayersBase;
long ClistBase;
long PotgoBase;
long TimerBase;
long xfiller15;
long xfiller16;
struct OLI strvar[] = {
"graphics", &GfxBase,
"intuition", &IntuitionBase,
"expansion", &ExpansionBase,
"diskfont", &DiskfontBase,
"translator", &TranslatorBase,
"icon", &IconBase,
"mathffp", &MathBase,
"mathtrans", &MathTransBase,
"mathieeedoubbas", &MathIeeeDoubBasBase,
"mathieeesingbas", &MathIeeeSingBasBase,
"layers", &LayersBase,
"clist", &ClistBase,
"potgo", &PotgoBase,
"timer", &TimerBase,
"x15", &xfiller15,
"x16", &xfiller16,
0L, 0L /* end marker for future compatibility */
};
openlibs(mask)
unsigned short mask;
{
register struct OLI *sv;
char buf[64];
long copymask = mask;
for (sv = &strvar[0]; mask && sv->name; mask >>= 1, ++sv) {
if (mask & 1) {
strcpy(buf, sv->name);
strcat(buf, ".library");
if (*sv->var == 0 && (*sv->var = OpenLibrary(buf, 0)) == 0)
goto fail;
}
}
return (1);
fail:
closelibs(copymask);
return (0);
}
SHAR_EOF
if test 1418 -ne "`wc -c openlibs.c`"
then
echo shar: error transmitting openlibs.c '(should have been 1418 characters)'
fi
echo shar: extracting resetbreak.c '(88 characters)'
cat << \SHAR_EOF > resetbreak.c
/*
* reset the break signal
*/
resetbreak()
{
SetSignal(0,SIGBREAKF_CTRL_C);
}
SHAR_EOF
if test 88 -ne "`wc -c resetbreak.c`"
then
echo shar: error transmitting resetbreak.c '(should have been 88 characters)'
fi
echo shar: extracting wildcmp.c '(843 characters)'
cat << \SHAR_EOF > wildcmp.c
/*
* Compare a wild card name with a normal name
*/
#define MAXB 8
wildcmp(wild, name)
char *wild, *name;
{
register char *w = wild;
register char *n = name;
char *back[MAXB][2];
int bi = 0;
while (*n || *w) {
switch (*w) {
case '*':
if (bi == MAXB) {
puts ("Too many levels of '*'");
return (0);
}
back[bi][0] = w;
back[bi][1] = n;
++bi;
++w;
continue;
goback:
--bi;
while (bi >= 0 && *back[bi][1] == '\0')
--bi;
if (bi < 0)
return (0);
w = back[bi][0] + 1;
n = ++back[bi][1];
++bi;
continue;
case '?':
if (!*n) {
if (bi)
goto goback;
return (0);
}
break;
default:
if (*n != *w) {
if (bi)
goto goback;
return (0);
}
break;
}
if (*n) ++n;
if (*w) ++w;
}
return (1);
}
SHAR_EOF
if test 843 -ne "`wc -c wildcmp.c`"
then
echo shar: error transmitting wildcmp.c '(should have been 843 characters)'
fi
echo shar: extracting xfio.c '(5958 characters)'
cat << \SHAR_EOF > xfio.c
/*
* XFIO.C
*
* Simple File IO with asyncronous READ and WRITE capability
* Perfect for protocol transfer applications
*
* xfi = xfopen(name, modes, bufsize) ("r", "w", "w+")
* n = xfread(xfi, buf, bytes) ASYNCRONOUS READ
* err = xfwrite(xfi, buf, bytes) ASYNCRONOUS WRITE
* err = xfclose(xfi)
*
* RESTRICTIONS: NO seeking. You can do one of xfread() or xfwrite()
* for a given open XFIle handle (not both).
*
* xfwrite() returns a cumulative error (once an error occurs, it will not
* do any more writes). xfclose() returns the cumulative write error
* (since the last write may have been asyncronous and thus the error
* unknown at the time).
*
* Two buffers are created each bufsize/2 bytes in size. for writing,
* one buffers is sent asyncronously while the other fills. For reading,
* one buffer is filling while the other is being read.
*/
#define XFI struct _XFI
#define XFBUF struct _XFBUF
#define MSGPORT struct MsgPort
#define FH struct FileHandle
#define STDPKT struct StandardPacket
XFBUF {
long bufsize;
long idx;
long max;
char buf[4]; /* actually bufsize bytes long */
};
XFI {
char ro; /* read only, else write only */
char pend; /* packet pending */
char err; /* cumulative error */
char reserved;
XFBUF *asbuf;
XFBUF *usbuf;
FH *fh;
STDPKT sp; /* asyncronous message */
MSGPORT rp; /* reply port for pending pkts */
};
extern FH *Open();
extern void *malloc(), *FindTask();
void *
xfopen(file, mode, bytes)
char *file;
char *mode;
{
register XFI *xfi = malloc(sizeof(XFI));
register long nbytes = bytes >> 1;
int ap = 0;
bzero(xfi, sizeof(XFI));
if (mode[0] == 'w') {
if (mode[1] == '+') {
ap = 1;
if ((xfi->fh = Open(file, 1005)) == NULL)
xfi->fh = Open(file, 1006);
goto ok;
}
xfi->fh = Open(file, 1006);
goto ok;
}
xfi->fh = Open(file, 1005);
ok:
if (xfi->fh) {
if (ap)
Seek(xfi->fh, 0, 1);
xfi->fh = (FH *)((long)xfi->fh << 2);
xfi->asbuf = malloc(sizeof(XFBUF) + nbytes); /* a little more */
xfi->usbuf = malloc(sizeof(XFBUF) + nbytes); /* then we need */
bzero(xfi->asbuf, sizeof(XFBUF));
bzero(xfi->usbuf, sizeof(XFBUF));
xfi->ro = (mode[0] == 'r');
xfi->asbuf->bufsize = xfi->usbuf->bufsize = nbytes;
xfi->rp.mp_Node.ln_Type = NT_MSGPORT;
xfi->rp.mp_Node.ln_Name = "XFIO-Async";
xfi->rp.mp_Flags = PA_SIGNAL;
xfi->rp.mp_SigBit = AllocSignal(-1);
xfi->rp.mp_SigTask = FindTask(NULL);
NewList(&xfi->rp.mp_MsgList);
if (xfi->ro)
xfstartasync(xfi, ACTION_READ);
} else {
free(xfi);
xfi = NULL;
}
return(xfi);
}
xfclose(xfi)
register XFI *xfi;
{
int err = 1;
if (xfi) {
if (xfi->pend) {
xfi->pend = 0;
WaitPort (&xfi->rp);
GetMsg (&xfi->rp);
}
if (!xfi->ro && xfi->usbuf->idx)
Write((long)xfi->fh >> 2, xfi->usbuf->buf, xfi->usbuf->idx);
err = xfi->err;
Close((long)xfi->fh >> 2);
free(xfi->asbuf);
free(xfi->usbuf);
FreeSignal(xfi->rp.mp_SigBit);
free(xfi);
}
return(err);
}
xfgets(xfi, buf, n)
XFI *xfi;
char *buf;
{
register XFBUF *usbuf = xfi->usbuf;
register int i, idx;
if (!xfi->ro)
return(-1);
--n;
for (i = 0;;) {
for (idx = usbuf->idx; idx < usbuf->max && i < n; ++idx, ++i) {
if ((buf[i] = usbuf->buf[idx]) == '\n') {
buf[i] = 0;
usbuf->idx = idx+1;
return(i);
}
}
usbuf->idx = idx;
buf[i] = 0;
if (i == n)
return(i);
if (xfi->pend == 0) /* EOF */
return(-1);
WaitPort (&xfi->rp);
GetMsg (&xfi->rp);
xfi->pend = 0;
if (xfi->sp.sp_Pkt.dp_Res1 <= 0) { /* EOF */
if (i == 0)
return(-1);
return(i);
}
xfi->asbuf->max = xfi->sp.sp_Pkt.dp_Res1;
xfi->asbuf->idx = 0;
usbuf = xfi->asbuf; /* swap bufs*/
xfi->asbuf = xfi->usbuf;
xfi->usbuf = usbuf;
xfstartasync(xfi, ACTION_READ); /* new async*/
}
}
xfread(xfi, buf, n)
XFI *xfi;
char *buf;
{
register XFBUF *usbuf = xfi->usbuf;
register int orig = n;
register int diff;
if (!xfi->ro)
return(0);
while ((diff = usbuf->max - usbuf->idx) < n) {
movmem(usbuf->buf + usbuf->idx, buf, diff); /* copy entire buf */
buf += diff;
n -= diff;
if (xfi->pend == 0) {
xfi->usbuf->idx = xfi->usbuf->max;
return(orig - n);
}
WaitPort (&xfi->rp);
GetMsg (&xfi->rp);
xfi->pend = 0;
if (xfi->sp.sp_Pkt.dp_Res1 <= 0) { /* EOF */
xfi->usbuf->idx = xfi->usbuf->max;
return(orig - n);
}
xfi->asbuf->max = xfi->sp.sp_Pkt.dp_Res1;
xfi->asbuf->idx = 0;
usbuf = xfi->asbuf; /* swap bufs*/
xfi->asbuf = xfi->usbuf;
xfi->usbuf = usbuf;
xfstartasync(xfi, ACTION_READ); /* new async*/
}
movmem(usbuf->buf + usbuf->idx, buf, n);
usbuf->idx += n;
return(orig);
}
xfwrite(xfi, buf, n)
XFI *xfi;
char *buf;
{
register XFBUF *usbuf = xfi->usbuf;
register int diff;
if (xfi->ro || xfi->err)
return(1);
while ((diff = usbuf->bufsize - usbuf->idx) < n) {
movmem(buf, usbuf->buf + usbuf->idx, diff); /* copy buf */
buf += diff;
n -= diff;
if (xfi->pend) {
WaitPort(&xfi->rp);
GetMsg (&xfi->rp);
xfi->pend = 0;
if (xfi->sp.sp_Pkt.dp_Res1 != xfi->sp.sp_Pkt.dp_Arg3) {
xfi->err = 1;
return(1);
}
}
usbuf = xfi->asbuf;
xfi->asbuf = xfi->usbuf;
xfi->usbuf = usbuf;
usbuf->idx = 0;
xfstartasync(xfi, ACTION_WRITE);
}
movmem(buf, usbuf->buf + usbuf->idx, n);
usbuf->idx += n;
return(xfi->err);
}
static
xfstartasync(xfi, action)
register XFI *xfi;
{
xfi->sp.sp_Msg.mn_Node.ln_Name = (char *)&(xfi->sp.sp_Pkt);
xfi->sp.sp_Pkt.dp_Link = &(xfi->sp.sp_Msg);
xfi->sp.sp_Pkt.dp_Port = &xfi->rp;
xfi->sp.sp_Pkt.dp_Type = action;
xfi->sp.sp_Pkt.dp_Arg1 = xfi->fh->fh_Arg1;
xfi->sp.sp_Pkt.dp_Arg2 = (long)xfi->asbuf->buf;
xfi->sp.sp_Pkt.dp_Arg3 = xfi->asbuf->bufsize;
PutMsg (xfi->fh->fh_Type, &xfi->sp);
xfi->pend = 1;
}
SHAR_EOF
if test 5958 -ne "`wc -c xfio.c`"
then
echo shar: error transmitting xfio.c '(should have been 5958 characters)'
fi
echo shar: extracting bcmp.asm '(1003 characters)'
cat << \SHAR_EOF > bcmp.asm
;BCMP.ASM
;
; If both source and dest are on longword boundries, and if the byte
; count is a multiple of 4, then use longword operations.
;
; if byte count < 16 then just use byte operations
;
; BCMP(p1,p2,n) return 0=failed, 1=compare ok
xdef _bcmp
_bcmp:
movem.l 4(A7),A0/A1 ;A0 = ptr1, A1 = ptr2
move.l 12(A7),D1 ;# bytes
andi.b #3,15(A7) ;# bytes multiple of 4?
bne onbyte
andi.b #3,7(A7) ;ptr1 on lwb?
bne onbyte
andi.b #3,11(A7) ;ptr2 on lwb?
bne onbyte
lsr.l #2,D1 ;YES, LONG COMPARE LOOP
clr.l D0 ;default return. Also sets Z flag
bra dropl
loopl cmpm.l (A0)+,(A1)+
dropl dbne.w D1,loopl
bne end
sub.l #$10000,D1
bpl loopl
addq.l #1,D0 ;return TRUE
rts
onbyte clr.l D0 ;default return. Also sets Z flag
bra dropb
loopb cmpm.b (A0)+,(A1)+ ;BYTE COMPARE
dropb dbne.w D1,loopb ;until count exhausted or compare failed
bne end
sub.l #$10000,D1 ;for buffers >65535
bpl loopb ;branch to loop because D0.W now is FFFF
addq.l #1,D0 ;return TRUE
end rts
SHAR_EOF
if test 1003 -ne "`wc -c bcmp.asm`"
then
echo shar: error transmitting bcmp.asm '(should have been 1003 characters)'
fi
echo shar: extracting bmov.asm '(1176 characters)'
cat << \SHAR_EOF > bmov.asm
;BMOV.ASM
; 4 8 12
;BMOV(src,dest,bytes)
;
; Matthew Dillon
;
; -Handles ascending/descending moves
; -Optimizes the move if addresses longword boundries and #bytes
; is a multiple of 4.
; -Completely tested
xdef _bmov
_bmov
movem.l 4(A7),A0/A1 ;source, destination
move.l 12(A7),D0 ;bytes
clr.b D1 ;long word boundry flag
andi.b #3,15(A7) ;byte count multiple of 4?
bne notlwb
andi.b #3,7(A7) ;source mulitple of 4?
bne notlwb
andi.b #3,11(A7) ;destination multiple of 4?
seq.b D1 ;set longword boundry flag if true
notlwb cmp.l A0,A1
beq end ;trivial case
ble ascend ;ascending copy
add.l D0,A0 ;descending copy
add.l D0,A1
decend tst.b D1 ;DESCEND
beq decbyte
declong lsr.l #2,D0 ;DESCEND LONGWORD
bra ab00
ab0 move.l -(A0),-(A1)
ab00 dbf.w D0,ab0
sub.l #$10000,D0
bpl ab0
end rts
ab1 move.b -(A0),-(A1) ;DESCEND BYTE
decbyte dbf.w D0,ab1
sub.l #$10000,D0
bpl ab1
rts
ascend tst.b D1 ;ASCEND
beq ascbyte
asclong lsr.l #2,D0 ;ASCEND LONGWORD
bra ab22
ab2 move.l (A0)+,(A1)+
ab22 dbf.w D0,ab2
sub.l #$10000,D0
bpl ab2
rts
ab3 move.b (A0)+,(A1)+ ;ASCEND BYTE
ascbyte dbf.w D0,ab3
sub.l #$10000,D0
bpl ab3
rts
SHAR_EOF
if test 1176 -ne "`wc -c bmov.asm`"
then
echo shar: error transmitting bmov.asm '(should have been 1176 characters)'
fi
echo shar: extracting bset.asm '(1076 characters)'
cat << \SHAR_EOF > bset.asm
;BSET.ASM
;BZERO.ASM
;
; Uses longword operations if data is aligned on a longword boundry
; and the size is a mulitple of 4. Otherwise, uses byte operations.
xdef _bset
xdef _bzero
_bzero
clr.l D1
bra begin
_bset
move.b 15(A7),D1 ;12(A7)-> msb . . lsb (D1 = data)
begin
move.l 4(A7),A0 ;A0 = address
move.l 8(A7),D0 ;D0 = byte count
andi.b #3,11(A7) ;byte count on long word boundry?
bne drop
andi.b #3,7(A7) ;address on longword boundry?
bne drop
bra lwb
loop move.b D1,(A0)+ ;BYTE SET LOOP
drop dbf.w D0,loop ;remember, only effects lower word
sub.l #$10000,D0 ;for buffers >65535
bpl loop ;branch to loop because D0.W now is FFFF
rts
lwb lsr.l #2,D0 ;byte count / 4 (longword chunks)
tst.l D1 ;BZERO
beq dropl
move.b D1,14(A7) ;15(A7) already contains the byte
move.w 14(A7),D1 ;D1 0..15 set
swap D1
move.w 14(A7),D1 ;D1 16..31 set
bra dropl
loopl move.l D1,(A0)+ ;BYTE SET LOOP
dropl dbf.w D0,loopl ;remember, only effects lower word
sub.l #$10000,D0 ;for buffers >65535
bpl loopl ;branch to loop because D0.W now is FFFF
rts
SHAR_EOF
if test 1076 -ne "`wc -c bset.asm`"
then
echo shar: error transmitting bset.asm '(should have been 1076 characters)'
fi
echo shar: extracting fhprintf.asm '(1670 characters)'
cat << \SHAR_EOF > fhprintf.asm
;FHPRINTF.ASM
;
; Handles formatted printing to Amiga file handles w/ fhprintf
;
; Manx assembler FAR stmts.
FAR code
FAR data
xdef _fhprintf
xref _Write
xref _LVORawDoFmt
xref _SysBase
_fhprintf
jsr xformat ;same thing
jsr _Write
lea.l 268(A7),A7
rts
;XFORMAT takes a Xprintf(xx, cs, arg, arg...) where xx is any
;integer and returns (xx, buf, bytes) on the stack suitable for an
;immediate call to xwrite() or Write(). The caller must deallocate
;268 bytes from the stack when done.
;
; (oret)
; A2 A3 A4 A5 A6 RET FI BUF NUM <thebuffer> printfret fi cs args
; ^ ^ ^
; 1 2 3
xformat
move.l A7,A0 ;sp now at pos. #3 A0 = pos #3
sub.l #268,A7 ;sp now at pos. #2 SP = pos #2
move.l (A0),(A7) ;copy return address
move.l 8(A0),4(A7) ;copy fi or fh to FI
lea.l 16(A7),A1 ;address of buffer
move.l A1,8(A7) ;place in BUF
movem.l A2-A6,-(A7) ;save regs SP = pos #1
move.l A1,A3 ;A3 = buffer pointer
lea.l 16(A0),A1 ;A1 = lea of printf arg list
move.l 12(A0),A0 ;A0 = control string
move.l #_xc,A2 ;A2 = call vector
move.l _SysBase,A6 ;exec library call
jsr _LVORawDoFmt(A6)
move.l 28(A7),A3 ;buffer start
loop tst.b (A3)+ ;find end of string
bne loop
sub.l 28(A7),A3 ;get string length
subq.l #1,A3
move.l A3,32(A7) ;place in NUM
movem.l (A7)+,A2-A6 ;restore registers used
rts
_xc
move.b D0,(A3)+
rts
SHAR_EOF
if test 1670 -ne "`wc -c fhprintf.asm`"
then
echo shar: error transmitting fhprintf.asm '(should have been 1670 characters)'
fi
echo shar: extracting dio.h '(4438 characters)'
cat << \SHAR_EOF > dio.h
/*
* DIO.H
*
* (C)Copyright 1987 Matthew Dillon, All Rights Reserved
* Freely distributable. Donations welcome, I guess.
*
* Matthew Dillon
* 891 Regal Rd.
* Berkeley, Ca. 94708
*
*/
#ifndef MYLIB_DIO_H
#define MYLIB_DIO_H
#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <devices/timer.h>
typedef struct IORequest IOR;
typedef struct IOStdReq STD;
typedef struct MsgPort PORT;
/*
* 'to' is in microsections. The IO request structure
* pointer is optional to dio_open(). If NULL, dio_open()
* initializes it's own IO request (to mostly zero). You have
* to provide an IO request structure, for instance, if openning
* a console device since the window pointer must be passed to
* OpenDevice().
*
* each DFD descriptor has it's own signal.
*
* dio_isdone() returns 1 if the channel is clear, 0 otherwise.
*/
extern long dio_open(); /* dfd = dio_open(devname,unit,flags,req)*/
extern long dio_dup(); /* newdfd = dio_dup(dfd) */
extern STD *dio_ctl(); /* req = dio_ctl(dfd,com,buf,len) */
extern STD *dio_ctl_to(); /* req = dio_ctl_to(dfd,com,buf,len,to) */
extern STD *dio_wait(); /* req = dio_wait(dfd) */
extern STD *dio_abort(); /* req = dio_abort(dfd) */
extern STD *dio_isdone(); /* req = dio_isdone(dfd) */
extern int dio_signal(); /* signm= dio_signal(dfd) */
extern void dio_close(); /* dio_close(dfd) */
extern void dio_cloesgroup(); /* dio_closegroup(dfd) */
extern void dio_cact(); /* dio_cact(dfd,bool) */
/*
* dio_simple() and related macros return the !io_Error field. That
* is, 0=ERROR, 1=OK
*
* dio_actual() returns the io_Actual field.
*
* NOTE: the io_Actual field may not be set by the device if an
* error condition exists. To make the io_ctl() and io_ctl_to()
* call automatically clear the io_Actual field before doing the
* io operation, use the DIO_CACT() call. The reason this isn't
* done automatically by default is that some devices require
* parameters to be passed in the io_Actual field (like the
* timer.device).
*
* Remember, Asyncronous IO is done by sending -com instead of com.
*
* CALL Syncronous IO Asyncronous IO
*
* dio_simple(dfd,com) 0=ERROR, 1=OK undefined
* dio_actual(dfd,com) io_Actual undefined
* dio_reset(dfd) 0=ERROR, 1=OK n/a
* dio_update(dfd) 0=ERROR, 1=OK n/a
* dio_clear(dfd) 0=ERROR, 1=OK n/a
* dio_stop(dfd) 0=ERROR, 1=OK n/a
* dio_start(dfd) 0=ERROR, 1=OK n/a
* dio_flush(dfd) 0=ERROR, 1=OK n/a
* dio_getreq(dfd) returns a ptr to the IO
* request structure
* NOTE: If you use the following, you probably want to have the
* device library automatically clear the io_Actual field before
* sending the request so you get 0 if an error occurs. That
* is: dio_cact(dfd,1);
*
*
* dio_read(dfd,buf,len) returns actual bytes read
* dio_write(dfd,buf,len) returns actual bytes written
*
* The timeout argument for dio_readto() and dio_writeto()
* is in MICROSECONDS, up to 2^31uS.
*
* dio_readto(dfd,buf,len,to) returns actual bytes read
* dio_writeto(dfd,buf,len,to) returns actual bytes written
*
* The asyncronous dio_reada() and dio_writea() do not
* return anything.
*
* dio_reada(dfd,buf,len) begin asyncronous read
* dio_writea(dfd,buf,len) begin asyncronous write
*/
#define dio_mask(dfd) (1 << dio_signal(dfd))
#define dio_simple(dfd,com) (!dio_ctl(dfd,com,0,0)->io_Error)
#define dio_actual(dfd,com) ( dio_ctl(dfd,com,0,0)->io_Actual)
#define dio_reset(dfd) dio_simple(dfd,CMD_RESET)
#define dio_update(dfd) dio_simple(dfd,CMD_UPDATE)
#define dio_clear(dfd) dio_simple(dfd,CMD_CLEAR)
#define dio_stop(dfd) dio_simple(dfd,CMD_STOP)
#define dio_start(dfd) dio_simple(dfd,CMD_START)
#define dio_flush(dfd) dio_simple(dfd,CMD_FLUSH)
#define dio_getreq(dfd) dio_ctl(dfd,0,0,0)
#define dio_read(dfd,buf,len) (dio_ctl(dfd,CMD_READ,buf,len)->io_Actual)
#define dio_write(dfd,buf,len) (dio_ctl(dfd,CMD_WRITE,buf,len)->io_Actual)
#define dio_readto(dfd,buf,len,to) (dio_ctl_to(dfd,CMD_READ,buf,len,to)->io_Actual)
#define dio_writeto(dfd,buf,len,to) (dio_ctl_to(dfd,CMD_WRITE,buf,len,to)->io_Actual)
#define dio_reada(dfd,buf,len) ((void)dio_ctl(dfd,-CMD_READ,buf,len))
#define dio_writea(dfd,buf,len) ((void)dio_ctl(dfd,-CMD_WRITE,buf,len))
#endif
SHAR_EOF
if test 4438 -ne "`wc -c dio.h`"
then
echo shar: error transmitting dio.h '(should have been 4438 characters)'
fi
echo shar: extracting typedefs.h '(2532 characters)'
cat << \SHAR_EOF > typedefs.h
/*
* TYPEDEFS.H
*/
#ifndef MYLIB_TYPEDEFS_H
#define MYLIB_TYPEDEFS_H
#ifdef INTUITION_INTUITION_H
typedef struct BitMap BITMAP;
typedef struct BoolInfo BOOLINFO;
typedef struct Border BORDER;
typedef struct Gadget GADGET;
typedef struct Image IMAGE;
typedef struct IntuiMessage INTUIMESSAGE;
typedef struct IntuiMessage IMESS;
typedef struct IntuiText INTUITEXT;
typedef struct IntuiText ITEXT;
typedef struct Menu MENU;
typedef struct MenuItem MENUITEM;
typedef struct MenuItem ITEM;
typedef struct NewScreen NEWSCREEN;
typedef struct NewScreen NS;
typedef struct NewWindow NEWWINDOW;
typedef struct NewWindow NW;
typedef struct Preferences PREFERENCES;
typedef struct Preferences PREFS;
typedef struct PropInfo PROPINFO;
typedef struct RastPort RASTPORT;
typedef struct RastPort RP;
typedef struct Remember REMEMBER;
typedef struct Requester REQUESTER;
typedef struct Screen SCR;
typedef struct StringInfo STRINGINFO;
typedef struct Window WINDOW;
typedef struct Window WIN;
#endif
#ifdef INTUITION_INTUITIONBASE_H
typedef struct GListEnv GLISTENV;
typedef struct GadgetInfo GADGETINFO;
typedef struct IBox IBOX;
typedef struct IntuitionBase INTUITIONBASE;
typedef struct IntuitionBase IBASE;
typedef struct PenPair PENPAIR;
typedef struct Point POINT;
#endif
#ifdef DEVICES_AUDIO_H
typedef struct IOAudio IOAUDIO;
typedef struct IOAudio IOA;
#endif
#ifdef DEVICES_BOOTBLOCK_H
typedef struct BootBlock BOOTBLOCK;
#endif
#ifdef DEVICES_CLIPBOARD_H
typedef struct IOClipReq IOCLIPREQ;
typedef struct IOClipReq IOCL;
typedef struct ClipboardUnitPartial CLIPUNIT;
typedef struct SatisfyMsg SATISFYMSG;
#endif
#ifdef DEVICES_CONUNIT_H
typedef struct ConUnit CONUNIT;
typedef struct IOStdReq IOCON;
#endif
#ifdef DEVICES_INPUTEVENT_H
typedef struct InputEvent INPUTEVENT;
typedef struct InputEvent IE;
#endif
#ifdef GRAPHICS_TEXT_H
typedef struct TextAttr TA;
typedef struct TextFont FONT;
#endif
#ifdef GRAPHICS_GELS_H
typedef struct VSprite VS;
typedef struct Bob BOB;
typedef struct AnimComp ANIMCOMP;
typedef struct AnimOb ANIMOB;
#endif
#ifdef GRAPHICS_RASTPORT_H
typedef struct GelsInfo GELSINFO;
#endif
#ifdef GRAPHICS_VIEW_H
typedef struct ViewPort VP;
#endif
#ifdef LIBRARIES_DOS_H
typedef struct Process PROC;
typedef struct Task TASK;
typedef struct FileInfoBlock FIB;
#endif
#ifdef DEVICES_TIMER_H
typedef struct timeval TV;
typedef struct timerequest TIMER;
#endif
#endif
SHAR_EOF
if test 2532 -ne "`wc -c typedefs.h`"
then
echo shar: error transmitting typedefs.h '(should have been 2532 characters)'
fi
echo shar: extracting xmisc.h '(644 characters)'
cat << \SHAR_EOF > xmisc.h
/*
* XMISC.H
*/
#ifndef MYLIB_XMISC_H
#define MYLIB_XMISC_H
#define GRAPHICS_LIB 0x0001L
#define INTUITION_LIB 0x0002L
#define EXPANSION_LIB 0x0004L
#define DISKFONT_LIB 0x0008L
#define TRANSLATOR_LIB 0x0010L
#define ICON_LIB 0x0020L
#define MATH_LIB 0x0040L
#define MATHTRANS_LIB 0x0080L
#define MATHIEEEDOUBBAS_LIB 0x0100L
#define MATHIEEESINGBAS_LIB 0x0200L
#define LAYERS_LIB 0x0400L
#define CLIST_LIB 0x0800L
#define POTGO_LIB 0x1000L
#define TIMER_LIB 0x2000L
struct OLI {
char *name;
long *var;
};
typedef struct _XLIST {
struct _XLIST *next, **prev;
} XLIST;
#endif
SHAR_EOF
if test 644 -ne "`wc -c xmisc.h`"
then
echo shar: error transmitting xmisc.h '(should have been 644 characters)'
fi
# End of shell archive
exit 0