home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d02xx / d0216.lha / BackDrop / src / res.a < prev    next >
Text File  |  1989-06-02  |  7KB  |  141 lines

  1. *:ts=8
  2. *****************************************************************************
  3. *                                                                           *
  4. * RES.A                                    (C) Copyright Eddy Carroll 1989  *
  5. *                                                                           *
  6. * This module allows you to make a duplicate copy of your current process.  *
  7. * In fact, both processes actually share the same code. However, the        *
  8. * seglist pointer of the current process is modified so that when the       *
  9. * process terminates, the memory doesn't get freed (if it did, the new      *
  10. * process would suddenly find itself deallocated. Hello guru...)            *
  11. * This code only works when called from CLI processes.                      *
  12. *                                                                           *
  13. * The parameters passed are similar to those for CreateProc(), with the     *
  14. * difference that instead of passing a BPTR to a seglist, you pass the      *
  15. * address of the function the new process should start executing at.        *
  16. *                                                                           *
  17. * When the new process returns from this function, it will be removed from  *
  18. * the system, and its memory (finally) deallocated.                         *
  19. *                                                                           *
  20. * The typical use for a function like this is to allow a program to detach  *
  21. * itself from a CLI (completely, with no trailing console handles etc.)     *
  22. * when it is run. This is a convenient feature for the user, if the program *
  23. * is of the sort designed to sit in the background the whole time, rather   *
  24. * than do something immediately, then exit.                                 *
  25. *                                                                           *
  26. * Lattice provide cback.o which on first look would seem to provide a       *
  27. * similar solution. However, cback.o makes it difficult to print error      *
  28. * messages to the console if there is an error on the command line - by     *
  29. * the time you spot the error, the CLI prompt has already been printed      *
  30. * and your error message is printed after it. This looks very messy.        *
  31. * In addition, cback.o doesn't let you shut the CLI window after detaching  *
  32. * a process, which can be annoying. res doesn't suffer from any such        *
  33. * inhibitions.                                                              *
  34. *                                                                           *
  35. * From C, you call it as follows:                                           *
  36. *                                                                           *
  37. * pid = res(name,pri,func,stacksize)                                        *
  38. *                                                                           *
  39. * name         - pointer to null terminated string                          *
  40. * pri          - integer, priority of the new process                       *
  41. * func         - pointer to the function for new process to call            *
  42. * stacksize    - integer, size of the stack for the new process             *
  43. *                                                                           *
  44. * pid          - Process ID of new process, or 0 if none created            *
  45. *                                                                           *
  46. *****************************************************************************
  47.  
  48.     INCLUDE "exec/types.i"
  49.         INCLUDE "exec/alerts.i"
  50.         INCLUDE "exec/nodes.i"
  51.         INCLUDE "exec/lists.i"
  52.         INCLUDE "exec/ports.i"
  53.         INCLUDE "exec/libraries.i"
  54.         INCLUDE "exec/tasks.i"
  55.         INCLUDE "libraries/dos.i"
  56.         INCLUDE "libraries/dosextens.i"
  57.         INCLUDE "workbench/startup.i"
  58.         INCLUDE "exec/funcdef.i"
  59.         INCLUDE "exec/exec_lib.i"
  60.         INCLUDE "libraries/dos_lib.i"
  61.  
  62.     xref    SysBase
  63.     xref    DOSBase
  64.     xdef    res
  65.  
  66. AbsExecBase    equ    4
  67. segsize        equ    36        ; Size of fake seg. (code = 28 bytes)
  68.  
  69.         csect   text,0,0,1,2        * xref's after this are 16-bit reloc
  70.  
  71.     xref    exit
  72.  
  73. callsys macro
  74.         CALLLIB _LVO\1
  75.     endm
  76.  
  77.  
  78. res:
  79.     movem.l    d2-d4/a2/a3/a6,-(a7)    ; Save registers
  80.     move.l    AbsExecBase.w,a6    ; Get base of Exec library
  81.     moveq    #0,d1            ; Any sort of memory will do
  82.     moveq    #segsize,d0        ; Get size of fake segment
  83.     callsys    AllocMem        ; Grab some memory
  84.     tst.l    d0            ; Did we get any?
  85.     beq    fatal            ; If not, abort immediately!
  86.     move.l    d0,a3            ; Save pointer to memory
  87.     sub.l    a1,a1            ; NULL pointer indicates our process
  88.     callsys    FindTask        ; Get pointer to our process block
  89.     move.l    d0,a2            ; Save it
  90.     move.l    pr_CLI(A2),a0        ; Get BPTR to our process's segarray
  91.     add.l    a0,a0            ; Convert BPTR to address
  92.     add.l    a0,a0            ; 
  93.     move.l    cli_Module(a0),4(a3)    ; Make fake segment point to our code
  94.     clr.l    cli_Module(a0)        ; Remove process seg. from CLI seglist
  95.     move.l    #segsize,(a3)        ; Set size of fake seglist
  96.     lea.l    8(a3),a2        ; Get pointer to first code byte
  97.  
  98. ;
  99. ; Now a tiny machine code program is constructed. It looks like this:
  100. ;
  101. ;    move.l    #$xxxxxx,A4    ; Initialise A4
  102. ;    jsr    $xxxxxx        ; Call user program
  103. ;    move.l    #$xxxxxx,A6    ; Load DOSbase into A6
  104. ;    move.l    #$xxxxxx,d1    ; Get BPTR to this segment 
  105. ;    jmp    UnLoadSeg(A6)    ; Unload our process from memory
  106. ;
  107. ; It's built "on the fly" so to speak, to keep code size down, and also
  108. ; because it's a convenient way of initialising all the variables.
  109. ; Note that a potential problem exists if DOSBase should somehow alter or
  110. ; disappear. We'll assume it will remain relatively stable for the next
  111. ; few years anyway :-)
  112. ;
  113.  
  114.     move.l    DOSBase,a6        ; Prepare for DOS call
  115.     move.w    #$287C,(a2)+        ; Store MOVE.L $xxxxxx,A4 instruction
  116.     move.l    a4,(a2)+        ; Output value of A4 to initialise to
  117.     move.w    #$4EB9,(a2)+        ; Store JSR $xxxxxx
  118.     move.l    36(a7),(a2)+        ; followed by address of user function
  119.     move.w    #$2C7C,(a2)+        ; Store MOVE.L $xxxxxx,A6 instruction
  120.     move.l    a6,(a2)+        ; followeds by current DOSbase
  121. ;
  122.     lea    4(a3),a3        ; Now get seglist ptr to fake segment
  123.     move.l    a3,d3            ; and convert it to BPTR
  124.     lsr.l    #2,d3            ; D3 now has seglist ptr to fake seg
  125.     move.w    #$223C,(a2)+        ; Store MOVE.L $xxxxxx,D1 instruction
  126.     move.l    d3,(a2)+        ; Followed by BPTR to the segment
  127.     move.l    #$4EEEFF64,(a2)+    ; Store JMP UnLoadSeg(A6)
  128. ;
  129.     move.l    28(A7),d1        ; Get pointer to name
  130.     move.l    32(A7),d2        ; Get process priority
  131.     move.l    40(A7),d4        ; Get stacksize
  132.     move.l    d1,$03f0
  133.     callsys    CreateProc        ; Create new process
  134.     movem.l    (a7)+,d2-d4/a2/a3/a6    ; Pop registers
  135.     rts                ; Return
  136. fatal:
  137.     moveq    #120,d0            ; Set error exit code
  138.     jmp    exit            ; And exit
  139.  
  140.     end
  141.