; 
;    DOMINO:conofacevv.s                           DATE: 5-86   
;    O'Leary, Stewart, Van de Geijn    University of Maryland
;
;    Programmed by Stewart
;

;                      This is conoface 
;              (awaken, pause, finis, and invoke) 
;             for the Vax using the  cc  compiler 
;             and the  macro  assembler under VMS.
;
;  "awaken (nodep)"  activates  "nodeprog (nodep, initialp)", which
;  returns control either by a "return" (to set status=0), a
;  "pause()" (to set status=1), or a "finis()" (to set status=2).
;  "invoke(func, <args>) behaves like "func(<args>)" except
;  that the system stack pointer is used in place of the node
;  stack pointer.  Useful for keeping node stacks down to a
;  reasonable size.
;
; Register  usage:
;
;      r9   20(r10)  = address of node.program
;      r10  4(ap)    = address of node
;      r11  4(r10)   = node.status
;           28(r10)  = address of top of stack for node
;
       .entry  awaken,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
;                                               Get node information.
       movl    4(ap),r10      ; get node pointer
       movl    20(r10),r9     ; get call address
       movl    4(r10),r11     ; get status 
;                                               Save system environment. 
       pushl   ap             ; save system ap
       pushl   fp             ; save system fp
       moval   0(sp),syssp    ; save sp in syssp
;
       cmpl    r11,#0         ; check status
       beql    norestore      ; go to norestore if status=0
;
;                                               status=1: restore node
;                                               environment and return
;                                               to node program
;
       movl    28(r10),sp     ; restore node stack pointer
       movl    (sp)+,fp       ; restore fp register
       movl    (sp)+,ap       ; restore ap register
       ret                    ; return  to node program
;
;                                               status=0: call node prog
norestore:
       movl    #1,4(r10)      ; node.status = 1
       movl    32(r10),sp     ; get node stack pointer
       moval   initial,-(sp)  ; put address of initial on stack as argument
       pushl   r10            ; put nodep on stack as argument
       calls   #2,(r9)        ; call subroutine
;
;                                               node program "return":
;                                               set status=0, restore 
;                                               system environment, and
;                                               return to system.

norm:                         
       movl    syssp,sp       ; restore system sp
       movl    (sp)+,fp       ; restore fp register
       movl    (sp)+,ap       ; restore ap register
       movl    #0,4(r10)      ; node.status=0
       ret                    ; return to control    
;
;                                              pause:  save node envirn.,
;                                              restore system environment,
;                                              return to system.
       .entry  pause,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
       pushl   ap             ; save node's ap
       pushl   fp             ; save node's fp
       movl    sp,ap          ; copy node stack pointer to ap
       movl    syssp,sp       ; restore system stack pointer
       moval   0(ap),28(r10)  ; save node stack pointer
       movl    (sp)+,fp       ; restore system fp
       movl    (sp)+,ap       ; restore system ap
       ret                    ; return to control    
;           
;                                             finis: set status=2, restore
;                                             system environment, return
;                                             to system.
       .entry  finis,^m<>
       movl    syssp,sp       ; restore system stack pointer
       movl    (sp)+,fp       ; restore system fp
       movl    (sp)+,ap       ; restore system ap
       movl    #2,4(r10)      ; node.status = 2
       ret                    ; return to control    
;
;
;                                             invoke: restore system stack
;                                             pointer and invoke thefunction
;                                             specified by the firstargument
;                                             with the remaining arguments.
;
       .entry  invoke,^m<r9,r10,r11>
       moval   (sp),r11       ;save node stack pointer
       movl    syssp,sp       ;restore system stack pointer
       moval   0(ap),r10      ;loop pushing all but the
       movl    (ap),r9        ;first argument onto the stack
       mull2   #4,r9
       addl2   r9,r10
       movl    (ap),r9
loop:
       decl    r9
       bleq    out
       pushl   (r10)
       subl2   #4,r10
       brb     loop
out:
       movl    (ap),r9        ;invoke the function
       decl    r9
       movl    4(ap),r10
       calls   r9,(r10)
       movl    r11,sp
       ret
;
       .external syssp
       .external initial
       .end