home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / program / lynxlib / ccomon.s < prev    next >
Text File  |  1993-10-23  |  4KB  |  143 lines

  1. ; This source file is part of the LynxLib miscellaneous library by
  2. ; Robert Fischer, and is Copyright 1990 by Robert Fischer.  It costs no
  3. ; money, and you may not make money off of it, but you may redistribute
  4. ; it.  It comes with ABSOLUTELY NO WARRANTY.  See the file LYNXLIB.DOC
  5. ; for more details.
  6. ; To contact the author:
  7. ;     Robert Fischer \\80 Killdeer Rd \\Hamden, CT   06517   USA
  8. ;     (203) 288-9599     fischer-robert@cs.yale.edu
  9.  
  10. * Coroutine master
  11. * Uses C calling conventions
  12.  
  13. * Process control block structure
  14. * typedef enum {P_NEW, P_BLOCKED, P_READY, P_RUNNING, P_DEAD} procstate;
  15. *
  16. * typedef struct {
  17. *    proc_state state;        process state
  18. *    char *stack;            current stack pointer
  19. *    message *msg;            message value
  20. * } pcb
  21.  
  22. * PCB offsets
  23. stack        = 0
  24.  
  25. ; -------------------------------------------
  26. ; A PROCESS IS IDENTIFIED BY ITS STACK POINTER
  27. ; -------------------------------------------
  28.  
  29. * invoke(f, x, p)
  30. * Calls f(x) in process p.  Returns when p blocks or terminates.
  31. *    func *f;    Function to call
  32. *    LONG x;        argument to give it
  33. *    pcb *p;        process control block for that function
  34. *
  35.  
  36. _init_co_s::
  37. *    Pop parameters from master stack
  38.     move.l    4(sp), a2    ; function f
  39.     move.l    8(sp), d1    ; argument x
  40.     move.l    12(sp), a1    ; pcb address p
  41.  
  42.     move.l    stack(a1), a0
  43.  
  44. *    Almost call function
  45.     move.l    d1, -(a0)        ; push argument x
  46.     move.l    #term, -(a0)    ; Push termination address
  47.     move.l    a2, -(a0)        ; Push resume() address
  48.     lea        -36(a0), a0        ; Dummy-save the registers
  49.  
  50.     move.l    a0, stack(a1)
  51.     rts
  52.  
  53. term:
  54. * Switch to master stack
  55.     move.l    resume_sp, a0
  56.     move.l    (a0)+, sp
  57.     move.l    a0, resume_sp
  58.     movem.l    (sp)+, a3-a6/d3-d7
  59.  
  60. *    Don't need to save slave's stack pointer because slave is DEAD
  61.  
  62. *    Return to master for good
  63.     move.l    #0, d0        ; Put a FALSE in d0 to indicate f has terminated
  64.     rts
  65.  
  66. * ----------------------------------------------------------------------
  67.  
  68. * BOOLEAN resume(p, m, ret_msg)
  69. *    pcb *p;
  70. *    message m;
  71. *    message *ret_msg;    Return message from slave
  72. * returns FALSE if p terminates, TRUE if it's still going
  73. *
  74. * Called by master.
  75. * Resumes process p, which should be in state P_READY.
  76. * Passes p.msg to the resumed process as a returned value.
  77.  
  78. _resume_co::
  79. *    Pick up argument
  80.     move.l    4(sp), a1    ; pointer to slave's stack pointer
  81.     move.l    8(sp), d0    ; Message for resumed process
  82.  
  83. *    Prepare for eventual return to master
  84.     movem.l    a3-a6/d3-d7, -(sp)
  85.  
  86. *    Push master's sp onto resume_stack
  87.     move.l    resume_sp, a0
  88.     move.l    sp, -(a0)
  89.     move.l    a0, resume_sp
  90.  
  91. *    Switch stacks to slave stack
  92.     move.l    stack(a1), sp
  93.  
  94. *    Return to slave from rendezvous
  95.     ; return message in d0 (above)
  96.     movem.l    (sp)+, a3-a6/d3-d7    ; restore registers
  97.     rts            ; return
  98.  
  99. * ----------------------------------------------------------------------
  100.  
  101. * message to_master(to_msg)
  102. *    message to_msg
  103. *
  104. * Called by slave function.
  105. * Blocks current process and passes control back to master.
  106. * When process is resumed, the message in the pcb is passed as
  107. * the value of the function.
  108.  
  109. _to_master::
  110.  
  111. *    Save things about slave's stack
  112.     move.l    4(sp), d1    ; slave's message
  113.     movem.l    a3-a6/d3-d7, -(sp)    ; save registers
  114.     move.l    sp, d0        ; save slave's stack pointer
  115.  
  116. *    Switch to master's stack
  117.     move.l    resume_sp, a0
  118.     move.l    (a0)+, sp
  119.     move.l    a0, resume_sp
  120.     movem.l    (sp)+, a3-a6/d3-d7
  121.  
  122. *    Find stack** variable on master's stack & store slave's stack * in it
  123.     move.l    4(sp), a0
  124.     move.l    d0, (a0)    ; Save into pcb
  125.  
  126. * Store away slave's message
  127.     move.l    12(sp), a0
  128.     move.l    d1, (a0)    ; Stuff slave's message into *ret_msg
  129.  
  130.     move.l    #-1, d0        ; Put a TRUE in d0 to indicate f has not terminated
  131.     rts
  132.  
  133. * ----------------------------------------------------------------------
  134.     .bss
  135.  
  136. ; In this stack, every time resume() is called, the pcb * of the process
  137. ; being resumed is pushed on the stack.  At tell_master, this is popped
  138. ; off the stack so tell_master() can tell which process is returning
  139. resume_stack : ds.l    100
  140. resume_end :            ; End of resume stack
  141.     .data
  142. resume_sp : dc.l resume_end        ; Resume stack pointer
  143.