%from IMP %include Mcode
!
! >>> HANDCALL.IMP <<<
!
! Provides procedures which allow the descriptor of a procedure to be
! taken and later used to call it with 0, 1, or 2 arguments.
!

!
! >> GET <<
!
! Note that the following procedure will be grossly mis-specced (three times)
! by the %include file HANDCALL.
!
%external %integer %function Get %alias "3L___get_proc_desc"(%integer E, A)
                                                            {%routine X}
   %result = A     {just return the address of the entry pair}
%end

!
! >> CALL 0 <<
!
! Call a procedure by descriptor
!
%external %routine Call 0 %alias "3L___call_proc_0"(%integer Desc)
   {R0 = Desc = Address of procedure}
   *LDMDB _ Fp, <Sb, Fp, Sp, Link>      {restore call context}
   *MOV   _ Pc, R0                      {jump to the procedure}
%end

!
! >> CALL 1 <<
!
! Call a procedure with one integer argument by descriptor
!
%external %routine Call 1 %alias "3L___call_proc_1"(%integer Desc, Arg1)
   *LDMDB _ Fp, <Sb, Fp, Sp, Link>      {restore call context}
   *MOV   _ R4, R0                      {protect entry point}
   *MOV   _ R0, R1                      {set up the single parameter}
   *MOV   _ Pc, R4                      {jump to the procedure}
%end

!
! >> CALL 2 <<
!
! Call a procedure with two integer arguments by descriptor
!
%external %routine Call 2 %alias "3L___call_proc_2"(%integer Desc, Arg1, Arg2)
   *LDMDB _ Fp, <Sb, Fp, Sp, Link>      {restore call context}
   *MOV   _ R4, R0                      {protect entry point}
   *MOV   _ R0, R1                      {set up the first parameter}
   *MOV   _ R1, R2                      {set up the second parameter}
   *MOV   _ Pc, R4                      {jump to the procedure}
%end

!
! >> DUMMY 0 <<
!
%external %routine Dummy 0 %alias "3L___dummy_0"
%end

!
! >> DUMMY 1 <<
!
%external %routine Dummy 1 %alias "3L___dummy_1" ( %integer A )
%end

!
! >> DUMMY 2 <<
!
%external %routine Dummy 2 %alias "3L___dummy_2" ( %integer A, B )
%end
