[mod.computers.vax] Problem with VAX Ada and the screen manager

KVC@ENGVAX.UUCP ("Kevin Carosso") (11/01/86)

[VMS V4.4, VAX Ada V1.0]

VAX Ada has a mechanism that allows you to use VMS ASTs within Ada programs
by treating the AST as an event that can be handled by an ACCEPT statement
in a rendezvous.  This is documented in the Ada doc set, with examples.

The screen manager (SMG$) package has a facility called
SMG$ENABLE_UNSOLICITED_INPUT which "detects unsolicited input and calls
an AST routine in response".

Unfortunately, ENABLE_UNSOLICITED_INPUT cannot be used with the VAX Ada
mechanism described above.  You will get unhandled exceptions in the
Ada run-time library and bomb out with "ERRONEOUS PROGRAM".  It turns out
that the problem is traced to the fact that the SMG package calls the
"AST routine" with an argument list that does not conform to the description
of an AST argument list as documented in the System Services reference manual.
Normally, an AST routine is called by VMS with 5 arguments.  SMG adds one
argument of it's own to the *beginning* of the list of arguments and calls
your AST routine with 6.  Normally this is not a problem, but since the
Ada run-time library fiddles with the argument list to handle task scheduling
at the rendezvous, it breaks completely and gets an access violation attempting
to access an address through the argument which contains the value of the
PSL.

I believe that SMG is broken because it claims to call an AST routine but
does not pass an argument list for an AST routine, as documented in section
5.4 of the "System Services Reference Manual" and section 7.3.2 of
"VAX/VMS Internals and Data Structures"

Here is a very simple-minded fix I whipped up to get around this problem
for simple cases.  It could be expanded to handle arbitrary numbers of
pasteboards.

        /Kevin Carosso                  kvc%engvax.uucp@csvax.caltech.edu
         Hughes Aircraft Co.

--------------- ADA_SMG_BUG.MAR --------------------
        .Title  ADA_SMG_BUG

;++
;
; A little code to get around that fact that the SMG routine
; SMG$ENABLE_UNSOLICITED_INPUT calls the AST routine with 6 arguments
; and VAX Ada AST handlers in a rendezvous can only handle 5 arguments.
;
; Written by Kevin Carosso @ Hughes Aircraft, SCG/CTC, 31-OCT-1986 (boo!)
;
; Note that this code is non-reentrant and can only be called once
; to set up an unsolicited input on one pasteboard.  Also, the
; pasteboard ID is NOT passed to the AST handler, since you've only
; get one anyway.  We'll return SS$_BADPARAM if we are called more
; than once without being disabled.
;
; You should use the matching routine SMG_DISABLE_UNSOLICITED_INPUT_5
; so that we clean up properly.  You can then enable an unsolicited
; input for another AST handler and/or another pasteboard.
;
;--

        .Psect  ADA_SMG_BUG_DATA, noexe, rd, wrt

real_AST_routine:
        .long   0                       ; Space for saving real AST handler

        .Psect  ADA_SMG_BUG_CODE, exe, rd, nowrt

        .Entry  SMG_ENABLE_UNSOLICITED_INPUT_5, ^M<>

        movzwl  #SS$_BADPARAM, r0
        tstl    real_AST_routine        ; Make sure we haven't been used.
        bneq    done
        movl    8(ap), real_AST_routine ; Save his routine's address
        moval   AST_intercept, 8(ap)    ; Put our intercept into arg block
        callg   (ap), G^SMG$ENABLE_UNSOLICITED_INPUT
done:   ret

        .Entry  SMG_DISABLE_UNSOLICITED_INPUT_5, ^M<>

        clrl    real_AST_routine        ; Make sure we can get used again.
        callg   (ap), G^SMG$DISABLE_UNSOLICITED_INPUT
        ret

        .Entry  AST_intercept, ^M<>

        pushl   24(ap)                  ; Set up the args we really want
        pushl   20(ap)
        pushl   16(ap)
        pushl   12(ap)
        pushl    8(ap)
        calls   #5, @real_AST_routine   ; and call the real handler
        ret

        .End