home *** CD-ROM | disk | FTP | other *** search
- /* Res.C - Autodetach code for Manx in C
- **
- ** Thanks to Eddy Carrol for his groundwork in assembler. I rewrote it
- ** in C 'cause assembly isn't really my favourite language..
- ** (Eddy's code also contains a few potential bugs..)
- **
- ** Eddy writes good documentation, so get "CPUBlit" from Fred Fish and
- ** study the source code and docs there..
- **
- ** Synopsis for res:
- **
- ** struct Task *pid = res(char *name, int pri, int (*kickoff)(), int stack)
- **
- ** kickoff() will be spawned as a completely selfcontained process. Caller's
- ** code will not be UnLoadSeg'ed until kickoff() terminates (exit() is a no-no
- ** in kickoff(), use return(doscode)!)
- **
- ** There's more, so read Eddy's docs!
- **
- ** This file is part of the Powerpacker Patcher project.
- ** Copyright 1991, Michael Berg. (Thanx Eddy!)
- */
-
- #include <pragmas.h>
- #include <exec/types.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <exec/memory.h>
-
- struct FakeSeg
- {
- ULONG segsize;
- ULONG segptr;
- UWORD op_moveim_a4; ULONG reg_a4;
- UWORD op_jsrabs; int (*func)();
- UWORD op_moveim_a6; ULONG reg_a6;
- UWORD op_moveim_d1; ULONG reg_d1;
- UWORD op_jmpindir_a6; UWORD lvo_unloadseg;
- };
-
- #define SEGSIZE sizeof(struct FakeSeg)
-
- typedef struct Process PROCESS;
-
- extern struct DOSBase *DOSBase;
-
- /* Doesn't Manx have another way to get at a register..? */
- fetch_a4()
- {
- #asm
- move.l a4,d0
- #endasm
- }
-
- /* Well, here it is! */
- struct Task *res(char *name,int pri,int (*fptr)(),int stacksize)
- {
- register struct FakeSeg *fs;
-
- if (fs = (struct FakeSeg *)AllocMem(SEGSIZE,MEMF_PUBLIC))
- {
- register PROCESS *ThatsMe = (PROCESS *)FindTask(0);
- BPTR ourseg,CLI;
- struct Task *created;
-
- ourseg = ThatsMe->pr_CLI;
- CLI = ((struct CommandLineInterface *)BADDR(ourseg))->cli_Module;
- ((struct CommandLineInterface *)BADDR(ourseg))->cli_Module = (BPTR)0;
-
- fs->segptr = (ULONG)CLI;
- fs->segsize = SEGSIZE;
-
- fs->op_moveim_a4 = 0x287C;
- fs->reg_a4 = fetch_a4();
- fs->op_jsrabs = 0x4EB9;
- fs->func = fptr;
- fs->op_moveim_a6 = 0x2C7C;
- fs->reg_a6 = (ULONG)DOSBase;
- fs->op_moveim_d1 = 0x223C;
- fs->reg_d1 = ((ULONG)(&fs->segptr)) >> 2;
- fs->op_jmpindir_a6 = 0x4EEE;
- fs->lvo_unloadseg = 0xFF64;
-
- if (created = (struct Task *)CreateProc(name,pri,fs->reg_d1,stacksize))
- return(created);
- else
- {
- ((struct CommandLineInterface *)BADDR(ourseg))->cli_Module = CLI;
- FreeMem(fs,SEGSIZE);
- }
- }
-
- return(NULL);
- }
-