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)] ==============================================================================