[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference hydra::amiga_v1

Title:AMIGA NOTES
Notice:Join us in the *NEW* conference - HYDRA::AMIGA_V2
Moderator:HYDRA::MOORE
Created:Sat Apr 26 1986
Last Modified:Wed Feb 05 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:5378
Total number of notes:38326

2909.0. "Starting Tasks from a Task ?" by NBOSWS::FRIES () Tue Sep 12 1989 10:48

    How to START a task form an application WITHOUT waiting for it's
    termination? The language must be 'Aztec-C'.

    Why does th following code not work?
    	seg=LoadSeg("file");
    	CreateProc(seg);
    	...
    	UnLoadSeg(seg);
    
    What's about AddTask() ?
    
    Thanks
    Gerald
    
T.RTitleUserPersonal
Name
DateLines
2909.1WJG::GUINEAUImpossible ConcentrationTue Sep 12 1989 12:155
this months transactor has an example on using LoadSeg() et al.

buried in the "Creating an Amiga Device"  article.

John
2909.2But where is it?NBOSWS::FRIESTue Sep 12 1989 12:266
    I'm sorry of beeing an inexperienced guy.
    So, where can I get 'this months transactor'?
    
    Thanks
    Gerald
    
2909.3WJG::GUINEAUImpossible ConcentrationTue Sep 12 1989 13:2510
Sorry. 

It's a magazine called "Transactor For Amiga". Comes from somewhere in Canada.

Should be on news stands that carry Amiga mags.

If you wait till tonight, I'll type the short example in for you.


John
2909.4some docs to helpWJG::GUINEAUImpossible ConcentrationWed Sep 13 1989 00:0147

Here's a bit of the example. It was geared towards loading and starting a
device driver but here are the relevant parts for LoadSeg()

#include <exec/types.h>
#include <exec/libraries.h>
#include <exec/resident.h>
#include <exec/devices.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>



ULONG SegList,   /* BCPL seglist pointer */
      codeloc;   /* pointer to code */

main()
{

(device stuff ommited)

SegList = (ULONG)LoadSeg"mydev.device");    /* load code into memory */
if(!SegList) {
   printf("Can't load code!\n");
   exit(0);
};

/* make SegList BCPL pointer into a real pointer */
codeloc = SegList * 4;

(rest of device stuf ommited)

}




Also, I'm probably going to get into trouble for this (CB, what's the story
here?) but here are some docs from the 1.3 AutoDocs. WJG::AMIGA:DOCS.ZOO
will hang around till someone tells me to cut the sh*t :-)

This ZOO has docs for AddTask(), RemTask(), CreateProc(), LoadSeg(), UnloadSeg()

John


2909.5CopyWrong ;-)FRAMBO::BALZERChristian Balzer DTN:785-1029Wed Sep 13 1989 03:3617
    Re: .4
    
    You (and other EasyNet archive maintainers) could be in deep trouble
    indeed, if someone ever found out. 
    Now I'm not going to tell them, but...
    
    Gerald, since your node name indicates that you're in Germany, go
    on and gimme a call, will ya? :-)
    A nice way to get all the docs and a bit of support is by becoming
    a registered developer, which is relativly inexpensive...
    
    BTW, you might be in for similar trouble with Transactor for
    "duplicating" their copyrighted material here, John. ;-)
    
    Regards,
    
    <CB>
2909.6huh? Big Trouble?WJG::GUINEAUImpossible ConcentrationWed Sep 13 1989 08:094
Gone like the wind [docs.zoo]. Sorry!

John
2909.7NBOSWS::FRIESWed Sep 13 1989 11:029
    Thanks for your example, John.
    But how to start that application (not a device or handler)
    loaded by LoadSeg()? CreateProc() seems not to work (see 2909.0).
                                                                 
    CreateProc() needs the segment list as a BCPL pointer, which LoadSeg()
    supplies, I think. So segment_pointer<<=2L is not necessary (?)
    
    Gerald
    
2909.8WJG::GUINEAUImpossible ConcentrationWed Sep 13 1989 11:5020
If your example of CreateProc() was just as you used it,then that's the problem.
(i.e. you had CreateProc(seglist)  - 1 arg)

CreateProc() takes several args, the seglist being one (and not the first).

I deleted the DOCS.ZOO file out of <CB> instilled fear :-) But I could
get the synopsis of CreateProc() for you.


Also, that example used an offset of 8 bytes passed what the SegList pointer
was as the actual start of the code.

SegList = LoadSeg("program");
codeloc = SegList * 4;
codestart = codeloc + 8;



John
2909.9Complete ExampleNBOSWS::FRIESThu Sep 14 1989 03:4634
    Sorry.
    Here is the complete example (which does not work).
    
    struct Segment	*seg,*LoadSeg();
    
    main()
    {
    	printf("main1\n");
    	NewTask();
    	Delay(300L);		/* why not ? */
    	printf("main2\n");
    /*	UnLoadSeg(seg);	*/
    	exit(0);
    }
    
    NewTask()
    {
    	seg = LoadSeg("my_program");	/* my_program is only a
    					 * printf("Hello World\n");
    					 * or such.
    					 */
    
    	CreateProc("MYPROG",0L,seg,4000L);
    
    	/* Now there is a task called MYPROG, but the application
    	 * does NOT start.
    	 */
    }
    
    What's the mistake here (Or isn't it so easy) ?
    
    Thanks
    Gerald
    
2909.10WJG::GUINEAUImpossible ConcentrationThu Sep 14 1989 09:044
I'll try this out tonight after school and see if I can figure it out.


John
2909.11MILTSS::MILOSMilos Roberto TSC MilanThu Sep 14 1989 15:2311
    re: .9
    I think your problem could be what you expected from your
    "application".
    I suppose that a printf in the task "MYPROG" will not write on *YOUR*
    cli window.
    What about do a "fprintf" into some log file to see if the code is
    ever executed?                     
    
    Good coding....8-)
    Roberto.
    
2909.12the answerWJG::GUINEAUImpossible ConcentrationSat Sep 16 1989 14:0059
>    Why does th following code not work?
>    	seg=LoadSeg("file");
>    	CreateProc(seg);
>    	...
>    	UnLoadSeg(seg);
    




Well, I finally figured this one out.

Basically what was happening is that the program you LoadSeg()'ed 
(my_program) is compiled with the standard c startup module (c.o and _main) 
by default.

The "normal" flow of a compiled program is like this:

	<run program> 
	start   is called which is in c.o. start does some stuff for
		getting a vector area set up, opens dos.library for you and
		deals with ARGC and ARGV for CLI or WB startup and then calls 
		_main (UNDERSCORE main)
	_main   is called (which is in umain.c and is added in to your program
		when you compile it by lattice C). _main does some more 
		ARGC,ARGV stuff, again depending on CLI or WB startup. It deals
		with stdin and stdout (making a small window if run from WB) 
		and finally calls your main().
	main	does what your program was wtitten to do!

So you LoadSeg my_program. CreateProc calls it, which causes it to execute
the standard startup code - except this program (my_program) was not run in 
the "normal" way (i.e. not run from CLI or WB) so, because of reasons beyond 
this explination, the startup code thinks it was started from WorkBench - and
hangs in a WaitPort() call waiting for the startup message from workbench.

Your main never gets called!!!

The solution? HACK c.a and umain.c to death. For Lattice these are found
in LC:/Source/c.a, umain.c.

What I did was strip c.a down so all it does is set up the vector stuff,
open dos.library for you and call your main(). _main() (in umain.c) NEVER 
gets called!

The next reply is the c.a I hacked up and the reply after that is 
my_program.c that works.

REMEMBER!!! my_program executes in a very limited environment! No stdin, no
stdout, no NADA! All you have is dos.library so file I/O is ok. Intuition
stuff should also work fine so you can open windows and all. Also, ARGC and
ARGV are non existant.  

Have Fun!

John


2909.13HACKED c.a startup codeWJG::GUINEAUImpossible ConcentrationSat Sep 16 1989 14:01171
*
* Johns HACKED C initial startup procedure under AmigaDOS
* 
* Use the following command line to make c.o
* asm -u -iINCLUDE: c.a
*
        INCLUDE "exec/types.i"
        INCLUDE "exec/alerts.i"
        INCLUDE "exec/nodes.i"
        INCLUDE "exec/lists.i"
        INCLUDE "exec/ports.i"
        INCLUDE "exec/libraries.i"
        INCLUDE "exec/tasks.i"
        INCLUDE "exec/memory.i"
        INCLUDE "exec/execbase.i"
        INCLUDE "libraries/dos.i"
        INCLUDE "libraries/dosextens.i"
        INCLUDE "workbench/startup.i"
        INCLUDE "exec/funcdef.i"
        INCLUDE "exec/exec_lib.i"
        INCLUDE "libraries/dos_lib.i"

MEMFLAGS EQU    MEMF_CLEAR+MEMF_PUBLIC
AbsExecBase EQU 4

; some usefull macros:

callsys macro
        CALLLIB _LVO\1
        endm
        
        xdef    XCEXIT                 * exit(code) is standard way to leave C.
	xdef 	@XCEXIT

        xref    LinkerDB               * linker defined base value
        xref    _BSSBAS                * linker defined base of BSS
        xref    _BSSLEN                * linker defined length of BSS
	IFD	RESIDENT
        xref        RESLEN
        xref        RESBASE
	xref	NEWDATAL
	ENDC
	
*       library references

        section text,code

	xref	main		* go strait to main(), do not pass go...

        xref    _main                   * Name of C program to start with.
        xref    MemCleanup              * Free all allocated memory
        xref    __fpinit                * initialize floating point
        xref    __fpterm                * terminate floating point
	
start:
        move.l  a0,a2                  * save command pointer
        move.l  d0,d2                  * and command length
        lea     LinkerDB,a4            * load base register

        lea     _BSSBAS,a3             * get base of BSS
        moveq   #0,d1
        move.l  #_BSSLEN,d0            * get length of BSS in longwords
        bra.s   clr_lp                 * and clear for length given
clr_bss move.l  d1,(a3)+
clr_lp  dbf     d0,clr_bss
	

        move.l  AbsExecBase.W,a6
        move.l  a6,SysBase(A4)
        move.l  a7,_StackPtr(A4)       * Save stack ptr
        clr.l   WBenchMsg(A4)

*------ get the address of our task
	move.l	ThisTask(a6),A3

*-----  clear any pending signals
	moveq	#0,d0
	move.l	#$00003000,d1
	callsys	SetSignal
	

        move.l  a7,D0           * get top of stack
        sub.l   4(a7),D0        * compute bottom 
        add.l   #128,D0         * allow for parms overflow
        move.l  D0,_base(A4)    * save for stack checking
*------ attempt to open DOS library:
        bsr.w     openDOS


        jsr     __fpinit(PC)            * Initialize floating point
        jsr     main(PC)               * call C entrypoint
        moveq.l #0,d0                   * set successful status
        bra.s   exit2
*

XCEXIT:
        move.l  4(SP),d0                * extract return code
@XCEXIT:
exit2:
        move.l  d0,-(a7)
        move.l  _ONEXIT(A4),d0          * exit trap function?
        beq.s   exit3
        move.l  d0,a0
        jsr     (a0)
exit3   jsr     MemCleanup(PC)          * cleanup leftover memory alloc.
        move.l  AbsExecBase.W,a6
        move.l  DOSBase(A4),a1
        callsys CloseLibrary            * close Dos library

        jsr     __fpterm(PC)            * clean up any floating point

done_1c:

*------ this rts sends us back to DOS:
exitToDOS:
        MOVE.L  (A7)+,D0
        movea.l _StackPtr(a4),SP        * restore stack ptr
        rts
	
*-----------------------------------------------------------------------
noDOS:
                moveq.l #100,d0
                bra     exit2



*-----------------------------------------------------------------------
*  Open the DOS library:

openDOS
                lea     DOSName(PC),A1
                moveq.l #0,D0
                callsys OpenLibrary
                move.l  D0,DOSBase(A4)
                beq     noDOS
                rts

DOSName         dc.b    'dos.library',0

        section __MERGED,BSS
*
        xref    DOSBase

        xdef    NULL,SysBase,WBenchMsg
        xdef    curdir,_mbase,_mnext,_msize,_tsize
        xdef    _oserr,_OSERR,_FPERR,_SIGFPE,_ONERR,_ONEXIT,_ONBREAK
        xdef    _SIGINT
        xdef    _ProgramName,_StackPtr,_base

*
NULL           ds.b    4               *
_base          ds.b    4               * base of stack
_mbase         ds.b    4               * base of memory pool
_mnext         ds.b    4               * next available memory location
_msize         ds.b    4               * size of memory pool
_tsize         ds.b    4               * total size?
_oserr         equ     *
_OSERR         ds.b    4
_FPERR         ds.b    4
_SIGFPE        ds.b    4
_SIGINT        ds.b    4
_ONERR         ds.b    4
_ONEXIT        ds.b    4
_ONBREAK       ds.b    4
curdir         ds.b    4
SysBase        ds.b    4
WBenchMsg      ds.b    4
_StackPtr      ds.b    4
stdin          ds.b    4
_ProgramName   ds.b    4
               END
2909.14my_program.cWJG::GUINEAUImpossible ConcentrationSat Sep 16 1989 14:1138
/*
 * my_program.c - intended to be LoadSeg'ed and CreateProc'ed from
 * another program.
 *
 * 	lc my_program
 * 	blink with my_program.lnk
 *
 * my_program.lnk:
 *
 *	FROM "c.o"+"my_program.o"
 *	TO "my_program"
 *	LIB LIB:lc.lib LIB:amiga.lib
 *	BATCH
 *
 * NOTICE the FROM "c.o" which is the compiled version of the previous reply.
 * Normally this is LIB:c.o which is Lattice's standard startup code.
 *
 */

#include <stdio.h>

main()
{
FILE *fp;

fp = fopen("ram:test","w");
if(!fp)
  exit(10);

fprintf(fp,"Hi");

fclose(fp);

exit(0);

   
}
2909.15GREAT !!!NBOSWS::FRIESMon Sep 18 1989 03:366
    GREAT !!!!
    Thank you VERY much.
    I hope Aztec will work, too.
    
    Gerald
    
2909.16WJG::GUINEAUImpossible ConcentrationMon Sep 18 1989 08:5710
Your welcome. I learned alot doing it!

I would think Aztec should work fine. You might need to change some formatting
for c.a, but other than that, who knows!


BTW - There may even be a switch to say "toss the standard startup code
and use mine" or something like that.  Check it out...

John
2909.17To simulate a startup-message ?NBOSWS::FRIESFri Sep 22 1989 03:3114
    re .11:
    	No, 'fprintf(fp,"Hello World\n")' doesn't work, too.
    
    re .12/13:
    	Again: Great work, John.
    	But in this way, perhaps it's not possible to start 'commercial'
    	applications like compilers and such.
    	Isn't there a way to 'simulate' a startup-message from Workbench
    	after a call to 'CreateProc()' and all works fine ?
        So, how to call the PutMsg() ?
    
    Gerald
    
    
2909.18Browser, WBRun...FRAMBO::BALZERChristian Balzer DTN:785-1029Fri Sep 22 1989 03:4616
    Re: .17
    
    There is a program including sources called WBRun around, and something
    similar (also including sources) from Peter da Silva, which he uses
    to start applications from his Browser (Version 1.6). This source
    _should_ be all you need and it's on a Fish disk somewhere. If you
    can't locate it, I'll be able to tell you where to get it on Monday.
    
    Regards,
    
    <CB>
    
    P.S.
    
    My vice-president (Heiko Rath) is still waiting for your call. ;-)
    
2909.19WJG::GUINEAUImpossible ConcentrationFri Sep 22 1989 09:065

WJG::AMIGA: has WBRUN (source) and BROWSER16 (nosource)

john
2909.20No I/O from taskELMST::VERMAVirendra, MRO4-3/H10, DTN 297-5913Tue Oct 03 1989 10:086
I think you can't call Amiga DOS functions (such as I/O) from a task. This
is because I/O functions require more data structures that are not included
in the task structure. If your task needs to call Amiga DOS functions, a
process should be used rather than task.

Hope that helps.