phillip@cbmvax.cbm.UUCP (Phillip Lindsay) (10/15/86)
[]
An example that implements a AmigaDos Handler (device) in non-BCPL format by
using a new feature introduced in system software release 1.2.
What follows is a shar file which contains the following files:
makefile ... guess...make for both my-handler and ihand
my-handler.c ... this is the main handler module
misc.c ... this module contains support routines (packet handling)
ihand.c ... a program to install your device node
AddDosNode.asm ... some interface code for Aztec people who don't have
a library that supports 1.2
Phillip Lindsay - Amiga Technical Support
my-handler.shar:
***CUT HERE [ I HOPE MY SIGNATURE DIDN'T SNEAK IN ]
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# makefile
# my-handler.h
# ihand.c
# misc.c
# my-handler.c
# adddosnode.asm
# This archive created: Wed Oct 15 16:29:52 1986
export PATH; PATH=/bin:$PATH
echo shar: extracting "'makefile'" '(538 characters)'
if test -f 'makefile'
then
echo shar: will not over-write existing file "'makefile'"
else
sed 's/^ X//' << \SHAR_EOF > 'makefile'
X# MY-HANDLER - Phillip Lindsay - (C) Commodore 1986
X#
X#
X
X#DEBUG = -dDEBUG
X
X#DFILE = df0:lib/myprintf.o
X#DFILE = df0:lib/debug.o
X
XCFLAGS = +lcd -dMANX $(DEBUG)
X
XLIBS = $(DFILE) -lc32
X
XOFILES = my-handler.o misc.o
XHFILES = my-handler.h
X
X
X.asm.o:
X as $*.asm
X
Xall: allhand ihand
X
Xallhand: $(OFILES)
X ln -w $(OFILES) $(LIBS)
X
Xmy-handler.o: my-handler.c $(HFILES)
X
Xmisc.o : misc.c $(HFILES)
X
X# here is the install program
X
Xihand: ihand.o adddosnode.o
X ln -w ihand.o adddosnode.o -lc32
X
Xihand.o: ihand.c
X
Xadddosnode.o: adddosnode.asm
SHAR_EOF
if test 538 -ne "`wc -c < 'makefile'`"
then
echo shar: error transmitting "'makefile'" '(should have been 538 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'my-handler.h'" '(325 characters)'
if test -f 'my-handler.h'
then
echo shar: will not over-write existing file "'my-handler.h'"
else
sed 's/^ X//' << \SHAR_EOF > 'my-handler.h'
X/* my-handler.h - Phillip Lindsay (C) Commodore 1986
X * You may freely distribute this source and use it for Amiga Development -
X * as long as the Copyright notice is left intact.
X *
X * globals and misc. data structures
X */
X
X
X/* global functions */
X
X#ifdef DEBUG
X
Xextern long kprintf();
X
X#endif
X
X/* EOF - my-handler.h */
SHAR_EOF
if test 325 -ne "`wc -c < 'my-handler.h'`"
then
echo shar: error transmitting "'my-handler.h'" '(should have been 325 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ihand.c'" '(2803 characters)'
if test -f 'ihand.c'
then
echo shar: will not over-write existing file "'ihand.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'ihand.c'
X/* ihand.c
X *
X * Install a AmigaDos Handler - ( dependent release 1.2 )
X *
X * 20-SEP-86 - Phillip Lindsay - (C) Commodore 1986
X * You may freely distribute this source and use it for Amiga Development -
X * as long as the Copyright notice is left intact.
X *
X * (! Please don't make using this routine a habit, release 1.2 WORKBENCH
X * greater than >33.43 offers a new mount command that will allow
X * specification of GlobalVec for non-BCPL modules - Thanks to Andy Finkel !)
X *
X * Example "DEVS:MOUNTLIST" :
X *------------------------------------------------------------------------------
X * MY0: Handler = l:my-handler
X * Stacksize = 5000
X * Priority = 5
X * GlobVec = 1
X * #
X *------------------------------------------------------------------------------
X */
X
X
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/expansion.h>
X#include <libraries/filehandler.h>
X#include <functions.h>
X
X#define OVER 0x02L /* BSTR overhead for size+NULL */
X
X#define HANDNAMESIZE (0x0cL+OVER) /* size of BSTR+NULL */
X#define HANDNAME "\x0cl:my-handler\0" /* BSTR format handler name */
X
X#define DEVNAMESIZE (0x03L+OVER) /* size of BSTR+NULL */
X#define DEVNAME "\x03MY0\0" /* BSTR of device name */
X
X#define PRIORITY 5L
X#define STACKSIZE 5000L
X#define GLOBALVEC -1L
X
XULONG ExpansionBase; /* for expansion library (1.2) */
X
Xmain()
X{
X
X struct DeviceNode *mynode;
X
X UBYTE *handname;
X
X UBYTE *devname;
X
X
X handname = AllocMem((ULONG)(HANDNAMESIZE),MEMF_PUBLIC | MEMF_CLEAR);
X if(!handname)
X exit(TRUE);
X strcpy(handname,HANDNAME);
X
X devname = AllocMem((ULONG)(DEVNAMESIZE),MEMF_PUBLIC | MEMF_CLEAR);
X if(!devname)
X {
X FreeMem(handname,(ULONG)(HANDNAMESIZE));
X exit(TRUE);
X }
X strcpy(devname,DEVNAME);
X
X mynode = AllocMem((ULONG)sizeof(*mynode),MEMF_PUBLIC | MEMF_CLEAR);
X
X if(!mynode)
X {
X FreeMem(handname,(ULONG)(HANDNAMESIZE));
X FreeMem(devname,(ULONG)(DEVNAMESIZE));
X exit(TRUE);
X }
X
X mynode->dn_Priority = PRIORITY;
X mynode->dn_StackSize = STACKSIZE;
X mynode->dn_GlobalVec = GLOBALVEC; /* (-1) the trick for non-bcpl module */
X mynode->dn_Name = (BSTR) ((ULONG)devname >> 2); /* to BPTR */
X mynode->dn_Handler = (BSTR) ((ULONG)handname >> 2); /* "" "" */
X
X/* This will fail if your not 1.2 */
X ExpansionBase = (ULONG) OpenLibrary(EXPANSIONNAME,0L);
X
X if(!ExpansionBase)
X {
X FreeMem(handname,(ULONG)(HANDNAMESIZE+2));
X FreeMem(devname,(ULONG)(DEVNAMESIZE+2));
X FreeMem(mynode,(ULONG)sizeof(*mynode));
X exit(TRUE);
X }
X
X AddDosNode(0L,0L,mynode);
X
X CloseLibrary(ExpansionBase);
X
X}
X
X/* EOF - ihand.c */
SHAR_EOF
if test 2803 -ne "`wc -c < 'ihand.c'`"
then
echo shar: error transmitting "'ihand.c'" '(should have been 2803 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'misc.c'" '(1704 characters)'
if test -f 'misc.c'
then
echo shar: will not over-write existing file "'misc.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'misc.c'
X/* misc.c - support routines - Phillip Lindsay (C) Commodore 1986
X * You may freely distribute this source and use it for Amiga Development -
X * as long as the Copyright notice is left intact.
X *
X * 30-SEP-86
X */
X
X#include <exec/types.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X#include <exec/ports.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X
X#ifdef MANX
X#include <functions.h>
X#endif
X
X/* returnpkt() - packet support routine
X * here is the guy who sends the packet back to the sender...
X *
X * (I modeled this just like the BCPL routine [so its a little redundant] )
X */
X
Xvoid returnpkt(packet,res1,res2)
X
Xstruct DosPacket *packet;
XULONG res1,res2;
X
X{
X struct Message *mess;
X struct MsgPort *replyport;
X struct Process *myproc;
X
X packet->dp_Res1 = res1;
X packet->dp_Res2 = res2;
X replyport = packet->dp_Port;
X mess = packet->dp_Link;
X myproc = (struct Process *) FindTask(0L);
X packet->dp_Port = &myproc->pr_MsgPort;
X mess->mn_Node.ln_Name = (char *) packet;
X mess->mn_Node.ln_Succ = NULL;
X mess->mn_Node.ln_Pred = NULL;
X
X PutMsg(replyport,mess);
X
X}
X
X
X/*
X * taskwait() ... Waits for a message to arrive at your port and
X * extracts the packet address which is returned to you.
X */
X
Xstruct DosPacket *taskwait()
X{
X struct Process *myproc;
X struct MsgPort *myport;
X struct Message *mymess;
X
X myproc = (struct Process *) FindTask(0L);
X myport = &myproc->pr_MsgPort;
X
X WaitPort(myport); /* wait for packet */
X mymess = (struct Message *) GetMsg(myport);
X
X/* give them the pointer to the packet */
Xreturn((struct DosPacket *) mymess->mn_Node.ln_Name);
X}
X
X/* end of misc.c */
SHAR_EOF
if test 1704 -ne "`wc -c < 'misc.c'`"
then
echo shar: error transmitting "'misc.c'" '(should have been 1704 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'my-handler.c'" '(7856 characters)'
if test -f 'my-handler.c'
then
echo shar: will not over-write existing file "'my-handler.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'my-handler.c'
X/* my-handler.c
X *
X * This is a "dumb" handler that can be used as a model.
X * Functionally this handler does nothing but "play pretend" so I suppose
X * you could classify my-handler as a NIL: AmigaDOS device.
X *
X * Phillip Lindsay (C) 1986 Commodore
X * You may freely distribute this source and use it for Amiga Development -
X * as long as the Copyright notice is left intact.
X *
X * (! Please note that support of non-BCPL modules
X * is a new feature in release 1.2 !)
X *
X * A sample "devs:mountlist" entry for a non-bcpl module:
X *
X * (! PLEASE NOTE: that this is supported ONLY by the MOUNT command on
X * 1.2 WORKBENCH release greater than 33.43 THANKS TO ANDY FINKEL !)
X *-----------------------------------------------------------------------------
X * MY0: Handler = l:my-handler
X * Stacksize = 5000
X * Priority = 5
X * GlobVec = 1
X * #
X * ----------------------------------------------------------------------------
X * Since most people will not have the new MOUNT command I have included
X * a program that uses the expansion.library to install the device node.
X *
X * But PLEASE don't distribute AmigaDOS device handlers that use a
X * "install program." The "mountlist" in almost all cases (except AUTOCONFIG)
X * should be taken advantage of for AmigaDOS device installation.
X *
X * I have done this under MANX, but I don't see too much trouble getting
X * it to work with Lattice...just don't use any startup code and
X * disable the stack checking on LC2 with '-v'.
X *
X */
X
X#include <exec/types.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X#include <exec/ports.h>
X#include <exec/libraries.h>
X#include <exec/devices.h>
X#include <exec/io.h>
X#include <exec/memory.h>
X#include <devices/console.h>
X#include <intuition/intuition.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X
X#ifdef MANX
X#include <functions.h>
X#endif
X
X#include "my-handler.h"
X
X/* my version of BADDR() has no problems with casting */
X#undef BADDR
X#define BADDR(x) ((APTR)((long)x << 2))
X
X#define ACTION_FIND_INPUT 1005L /* please refer to DOS Tech. Ref. */
X#define ACTION_FIND_OUTPUT 1006L
X#define ACTION_END 1007L
X
X#define DOS_FALSE 0L
X#define DOS_TRUE -1L /* BCPL "TRUE" */
X
X#ifdef MANX
XULONG SysBase, /* these are here to make the startup code happy */
X _savsp; /* (this is unique to Manx Aztec C startup) */
X#endif
X
X_main()
X{
X
X /* handler support routines */
X
X extern void returnpkt(); /* sends a packet back to sender */
X struct DosPacket *taskwait(); /* waits for packet from the world */
X
X
X /* handler related data structures */
X
X struct Process *myproc; /* my process */
X struct DosPacket *mypkt; /* a pointer to the dos packet sent */
X BSTR parmdevname; /* pointer to device name in parmpkt Arg1 */
X long parmextra; /* extra info passed in parmpkt Arg2 */
X struct DeviceNode *mynode; /* our device node passed in parmpkt Arg3 */
X struct FileHandle *fh; /* a pointer to our file handle */
X long open; /* handler open flag */
X long run; /* handler main loop flag */
X
X/* I have left all my debug's in...you'll see how they save you headaches
X * the first time you try to debug your handler...
X */
X
X#ifdef DEBUG
X kprintf("**** Start my-handler ****\n");
X#endif
X
X/* misc. init. */
X myproc = (struct Process *) FindTask(0L); /* find myself */
X open = DOS_FALSE; /* not open */
X run = TRUE; /* handler loop flag */
X
X/* since we were started as a non-BCPL module we get sent the parameter pkt */
X/* (ie. parameter packet not in D1) */
X
Xmypkt = taskwait(); /* wait for parameter packet */
X
X#ifdef DEBUG
X kprintf("Got Parmeter Packet.\n");
X#endif
X
X parmdevname = (BSTR) mypkt->dp_Arg1; /* BSTR name passed to handler */
X parmextra = mypkt->dp_Arg2; /* Extra Info passed */
X
X /* get pointer to our device node */
X mynode = (struct DeviceNode *) BADDR(mypkt->dp_Arg3); /* ptr to device node */
X
X /*
X * This is where you do your handler initialization
X * Open what ever devices ... parse the device name passed in
X * the parameter packet...etc...
X */
X
X
X/* if initialzation was possible then we... */
X
X mynode->dn_Task = &myproc->pr_MsgPort; /* install our taskid ...
X * if we don't...for every reference to our handler
X * a NEW process will be created. This is fine for
X * things like CON: (console handler) but if you
X * plan to be the only dude on block ( like the
X * file-system handler or SER: ) you should fill
X * the task field with your taskid
X * (ie. &(pr_MsgPort) )
X * Note: remember that shared code has to be
X * reentrant. (like CON: handler)
X * ( keep your variables on the stack [autos],
X * and allocate memory for larger data
X * structures and "FLAG" global data structures
X * that need only be intialized once )
X */
X#ifdef DEBUG
X kprintf("Returning parmeter packet...A-O-K.\n");
X#endif
X
Xreturnpkt(mypkt,DOS_TRUE,mypkt->dp_Res2); /* everything a-o-k */
X
X#ifdef DEBUG
X kprintf("Waiting for packet..\n");
X#endif
X
X while(run) /* start of the real work */
X {
X mypkt = taskwait(); /* wait for a packet */
X
X switch(mypkt->dp_Type)
X {
X case ACTION_FIND_INPUT: /* opening your device */
X case ACTION_FIND_OUTPUT:
X
X#ifdef DEBUG
X kprintf("Action FindInput/Ouput : %ld\n",mypkt->dp_Type);
X#endif
X
X fh = (struct FileHandle *) BADDR(mypkt->dp_Arg1);
X fh->fh_Port = DOS_TRUE;
X open++;
X returnpkt(mypkt,DOS_TRUE,mypkt->dp_Res2);
X break;
X
X case ACTION_END:
X
X#ifdef DEBUG
X kprintf("Action End : %ld\n",mypkt->dp_Type);
X#endif
X
X/* we want to fall out of the loop if not OPEN.
X */
X
X if((--open) <= 0) run = FALSE;
X
X returnpkt(mypkt,DOS_TRUE,mypkt->dp_Res2);
X break;
X
X case ACTION_READ:
X
X#ifdef DEBUG
X kprintf("Action Read : %ld\n",mypkt->dp_Type);
X#endif
X
X/* we *always* read nothing */
X
X returnpkt(mypkt,0L,mypkt->dp_Res2);
X break;
X
X case ACTION_WRITE:
X#ifdef DEBUG
X kprintf("Action Write : %ld\n",mypkt->dp_Type);
X#endif
X
X/* we *always* write everything */
X
X returnpkt(mypkt,mypkt->dp_Arg3,mypkt->dp_Res2);
X break;
X
X default:
X#ifdef DEBUG
X kprintf("Unknown packet type %ld\n",mypkt->dp_Type);
X#endif
X/* say what? */
X returnpkt(mypkt,DOS_FALSE,ERROR_ACTION_NOT_KNOWN);
X
X } /* end of switch(mypkt->dp_Type) */
X
X } /* end of while(run) */
X
X
X mynode->dn_Task = FALSE; /* zero the taskid field of device node */
X
X /* INSERT HERE -> do some clean up and leave */
X
X/* we are a process "so we fall off the end of the world" */
X
X/* If we are reentrant we can't rely on our initial stack being saved.
X * Which means NO exit()'s ... We must just fall through....If your
X * not reentrant then don't worry about ending here.
X *
X * BTW, you don't necessarlly have to leave...You could stick around and
X * wait all day for packets....its all according to what your handler
X * is set-up to do.
X */
X
X} /* end of _main() */
X
X
X
X/* EOF - end of my-handler */
SHAR_EOF
if test 7856 -ne "`wc -c < 'my-handler.c'`"
then
echo shar: error transmitting "'my-handler.c'" '(should have been 7856 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'adddosnode.asm'" '(602 characters)'
if test -f 'adddosnode.asm'
then
echo shar: will not over-write existing file "'adddosnode.asm'"
else
sed 's/^ X//' << \SHAR_EOF > 'adddosnode.asm'
X* AddDosNode.asm
X*
X* Interface code for AddDosNode() ...
X* 19-SEP-86 - Phillip Lindsay - (C) Commodore 1986
X* You may freely distribute this source and use it for Amiga Development -
X* as long as the Copyright notice is left intact.
X*
X* This is for AZTEC people who don't have a library that supports new functions
X*
X
X_LVOAddDosNode EQU -150
X
X XREF _ExpansionBase
X
X XDEF _AddDosNode
X
X
X_AddDosNode:
X
X move.l a6,-(sp)
X move.l _ExpansionBase,a6
X movem.l 8(sp),d0-d1/a0
X jsr _LVOAddDosNode(a6)
X move.l (sp)+,a6
X rts
X
X END
X
X* EOF
SHAR_EOF
if test 602 -ne "`wc -c < 'adddosnode.asm'`"
then
echo shar: error transmitting "'adddosnode.asm'" '(should have been 602 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--
==============================================================================
Phillip Lindsay - Commodore Business Machines - Amiga Technical Support
Dirt: 1200 Wilson Drive, West Chester PA 19380
uucp: {ihnp4|seismo|caip}!cbmvax!phillip
arpa: cbmvax!phillip@seismo -or- phillip@cbmvax.UUCP@{seismo | harvard}
Tel.: (215) 431-9180
Disclaimer: [someone said I needed this] No warranty is implied or otherwise
given in the form of suggestion or example. Any opinions found here are of
my making. [unless Fred pops up (my other self)]
==============================================================================