home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
620.lha
/
PP_v1.4
/
Source.LZH
/
Source
/
res.c
< prev
Wrap
C/C++ Source or Header
|
1991-12-21
|
2KB
|
95 lines
/* 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);
}