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 >
Wrap
Text File
|
1993-10-23
|
4KB
|
143 lines
; This source file is part of the LynxLib miscellaneous library by
; Robert Fischer, and is Copyright 1990 by Robert Fischer. It costs no
; money, and you may not make money off of it, but you may redistribute
; it. It comes with ABSOLUTELY NO WARRANTY. See the file LYNXLIB.DOC
; for more details.
; To contact the author:
; Robert Fischer \\80 Killdeer Rd \\Hamden, CT 06517 USA
; (203) 288-9599 fischer-robert@cs.yale.edu
* Coroutine master
* Uses C calling conventions
* Process control block structure
* typedef enum {P_NEW, P_BLOCKED, P_READY, P_RUNNING, P_DEAD} procstate;
*
* typedef struct {
* proc_state state; process state
* char *stack; current stack pointer
* message *msg; message value
* } pcb
* PCB offsets
stack = 0
; -------------------------------------------
; A PROCESS IS IDENTIFIED BY ITS STACK POINTER
; -------------------------------------------
* invoke(f, x, p)
* Calls f(x) in process p. Returns when p blocks or terminates.
* func *f; Function to call
* LONG x; argument to give it
* pcb *p; process control block for that function
*
_init_co_s::
* Pop parameters from master stack
move.l 4(sp), a2 ; function f
move.l 8(sp), d1 ; argument x
move.l 12(sp), a1 ; pcb address p
move.l stack(a1), a0
* Almost call function
move.l d1, -(a0) ; push argument x
move.l #term, -(a0) ; Push termination address
move.l a2, -(a0) ; Push resume() address
lea -36(a0), a0 ; Dummy-save the registers
move.l a0, stack(a1)
rts
term:
* Switch to master stack
move.l resume_sp, a0
move.l (a0)+, sp
move.l a0, resume_sp
movem.l (sp)+, a3-a6/d3-d7
* Don't need to save slave's stack pointer because slave is DEAD
* Return to master for good
move.l #0, d0 ; Put a FALSE in d0 to indicate f has terminated
rts
* ----------------------------------------------------------------------
* BOOLEAN resume(p, m, ret_msg)
* pcb *p;
* message m;
* message *ret_msg; Return message from slave
* returns FALSE if p terminates, TRUE if it's still going
*
* Called by master.
* Resumes process p, which should be in state P_READY.
* Passes p.msg to the resumed process as a returned value.
_resume_co::
* Pick up argument
move.l 4(sp), a1 ; pointer to slave's stack pointer
move.l 8(sp), d0 ; Message for resumed process
* Prepare for eventual return to master
movem.l a3-a6/d3-d7, -(sp)
* Push master's sp onto resume_stack
move.l resume_sp, a0
move.l sp, -(a0)
move.l a0, resume_sp
* Switch stacks to slave stack
move.l stack(a1), sp
* Return to slave from rendezvous
; return message in d0 (above)
movem.l (sp)+, a3-a6/d3-d7 ; restore registers
rts ; return
* ----------------------------------------------------------------------
* message to_master(to_msg)
* message to_msg
*
* Called by slave function.
* Blocks current process and passes control back to master.
* When process is resumed, the message in the pcb is passed as
* the value of the function.
_to_master::
* Save things about slave's stack
move.l 4(sp), d1 ; slave's message
movem.l a3-a6/d3-d7, -(sp) ; save registers
move.l sp, d0 ; save slave's stack pointer
* Switch to master's stack
move.l resume_sp, a0
move.l (a0)+, sp
move.l a0, resume_sp
movem.l (sp)+, a3-a6/d3-d7
* Find stack** variable on master's stack & store slave's stack * in it
move.l 4(sp), a0
move.l d0, (a0) ; Save into pcb
* Store away slave's message
move.l 12(sp), a0
move.l d1, (a0) ; Stuff slave's message into *ret_msg
move.l #-1, d0 ; Put a TRUE in d0 to indicate f has not terminated
rts
* ----------------------------------------------------------------------
.bss
; In this stack, every time resume() is called, the pcb * of the process
; being resumed is pushed on the stack. At tell_master, this is popped
; off the stack so tell_master() can tell which process is returning
resume_stack : ds.l 100
resume_end : ; End of resume stack
.data
resume_sp : dc.l resume_end ; Resume stack pointer